oxidecomputer / oxidecomputer/hubris

"Can this task panic" as part of its external interface?

Open
#1,716 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

🤔 design
Dominant language
Rust
Stars
3.6k
Forks
239
Avg merge
1d 12h
Merged PRs (30d)
23

Description

We're approaching having some core tasks that can't panic. (...other than idle, that is, which isn't an interesting case.)

We've always had one task that de facto can't panic in a working system: the supervisor. Since nobody will be there to restart it, the supervisor is not allowed to panic. (It currently technically can panic for compiler reasons but I'm working on it.)

We have other core tasks that can't panic in practice, such as stm32xx-sys and packrat.

@hawkw pointed out that it might be interesting to make this fact a property of their external (IPC) interface. This would let us simplify idol code generation and remove some illusory error cases / panics from their clients.

To be comfortable removing the error checking from clients, we'd need some assurance that the task can't panic. The userlib/no-panic feature I'm in the process of adding takes one step in that direction by not compiling in a #[panic_handler]. (Sort of; Rust doesn't actually support that but we're faking it using linker trickery.) However, such a task can still access the sys_panic syscall.

If we have some piece of metadata declaring that the task can't panic, it would be nice to close that hole. At minimum we probably want to detect it attempting to call sys_panic and do something about it, like convert it into a fault so the supervisor will record a crash instead of a panic, maybe? This doesn't help the clients, however, which were previously assured that this task could not panic, and generated code relying on this fact.

We could add some sort of post-build analysis step that looks for use of the syscall, but this would only catch deliberate uses of the syscall; in the event of an exploit, a task could wind up calling the syscall through non-obvious means.

We probably do not want to alter the syscall for such tasks such that it returns an error. What is the task to do with such an error? sys_panic is defined as returning ! in Rust, so, it can't return or we're in UB land.

A scary but effective solution here is: convert a panic in a no-panic task into a system restart. This ensures that no client will hit UB by observing the panic, and ensure that whatever sneaky method for calling the syscall we failed to detect statically isn't allowed to do any further damage. While I have some concerns about this as a fault amplifier, I think it's possibly the right decision....

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the userlib/no-panic feature, the sys_panic syscall, IPC interfaces, and idol code generation. Define how no-panic metadata is represented and enforced, including what happens when a task still attempts to panic, then verify that generated clients can safely rely on the guarantee.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
embedded-iot, operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.