Replies: 6 comments 14 replies
-
Excuse the rust neophyte question - what exactly does it mean to disallow panics? Does it mean the code won't compile if it might panic? (in which case I agree), or do panics get ignored? |
Beta Was this translation helpful? Give feedback.
-
No problem at all! There really isn't a first-class way to disable panics, but you can have build-time checks to ensure that the binary being produced does not have panics in it (and fail the build if panics are detected). Whether the compiler will generate a panic or not does depend on how inlining and various other compiler optimization steps interact with each other; so we couldn't guarantee that there were no panics for all permutations of compiler optimization and compilers, but we could at least guarantee that there were no panics present in a "default" build (where we get to define what the default build is). Making the default build have no panics would suffice for pretty much all practical purposes. |
Beta Was this translation helpful? Give feedback.
-
... and to go back to the question of what we want, and what the optimizing compiler actually gives us... Could/How would optimization create a panic-path in any of the 3 good examples? |
Beta Was this translation helpful? Give feedback.
-
thanks for the explanation. |
Beta Was this translation helpful? Give feedback.
-
I'm the author of In my experience, the biggest hurdle to enforcing a That is to say: unless you forgo using many of the helpful built-in APIs that ship with the Rust Depending on the optimization level + how clever the compiler happens to be that day, these panicking calls may be optimized out, but there's no way to know for-sure (outside of building the code + using something like Working on All that is to say: if no-panic is a property tpm-rs is seriously interested in, be aware of the many knock-on effects the decision will have:
Lastly, it should be noted that no-panic code may end up looking quite "alien" when compared to the equivalent idiomatic Rust code. It would be wise to get consensus from interested parties around whether or not such a strict no-panic policy is even required, as opposed to adopting less extreme methods of avoiding panics (e.g: fuzzing all public entry points into the TPM to ensure no payload can trigger a panic path, enforcing proper error-handling etiquette in code review, etc...) |
Beta Was this translation helpful? Give feedback.
-
Thank you Daniel for the very detailed explanation of what a no-panic style would require for the tpm-rs project! You were definitely able to articulate the points much better than I original did :) I agree that the decision to keep the tpm-rs project in the "no panic" realms will have a continual maintenance cost. I think starting off the project with the aim for no panic makes the cost more palatable and easier to keep in maintenance mode. I also agree that we could only guarantee the no panic statement for "tier 1" compiler toolchains, and that there would probably only be one (maybe two) tier 1 toolchains that CI would check. Having at least the tier 1 toolchain produce no panic paths goes a long way for all the other toolchains combinations for reducing the number of overall panics. I also agree that we should probably use |
Beta Was this translation helpful? Give feedback.
-
I think it would be nice if this project disallowed panics from the very start of the implementation. There are a couple of tricks you can do with
#[panic_handler]
to help ensure there are no panics. See https://github.com/chipsalliance/caliptra-sw/blob/ce64c4a6/runtime/src/main.rs#L106 and https://github.com/chipsalliance/caliptra-sw/blob/ce64c4a6/fmc/test-fw/test-rt/tests/test_panic_missing.rs for some ideas.Disallowing panics makes the implementation smaller since you do not have to carry around panic formatting code and it makes it more resilient.
The reason to start early with this, is because it often changes the way slices are accesses throughout the code. For example,
buffer[..HEADER_SIZE]
may or may not generate a panic under the hood depending on what kinds of checks precede that line and how much the optimizer can reason about the size ofbuffer
. The compiler won't emit a panic if you first check the bounds (e.g.if buf.len() < HEADER_SIZE { return; }
) before the access; otherwise you can accessbuffer
withbuffer.get(..HEADER_SIZE)
to avoid a panic. Usingget
also forces the caller to handle the case when the buffer isn't large enough.What thoughts does the team have on this topic?
Beta Was this translation helpful? Give feedback.
All reactions