-
Notifications
You must be signed in to change notification settings - Fork 356
Description
esp-hal has supports stack overflow protection using flip-link on esp32c6 and esp32h2, (unsure why it's limited to only two chips). But from what I can tell, this protection only applies when no heap is involved, and only for the "last" thread in a multithreaded SoC. It would be nice to have a more general stack overflow protection that works on a wider array of chips.
Here's what I've gathered so far on a potential solution: Non-embedded systems normally implement stack overflow protection by using a no access-permission guard-page at the end of a thread's stack region. All esp32 riscv chips seem to have Physical Memory Protection unit (PMP). Perhaps the PMP can be used by the rt crate to set up these guard pages? PMP checks in M-mode is mentioned in the RISC-V Vol. II manual, so this might work at the hardware level:
PMP checks are applied to [...] data accesses in M-mode when the MPRV bit in mstatus is set and the MPP field in mstatus contains S or U. ... Optionally, PMP checks may additionally apply to M-mode accesses, in which case the PMP registers themselves are locked, so that even M-mode software cannot change them until the hart is reset. In effect, PMP can grant permissions to S and U modes, which by default have none, and can revoke permissions from M-mode, which by default has full permissions.
Don't think that there's a negligible performance cost to adding guard pages, apart from reductions in available memory. But the feature and page size should probably be made configurable nonetheless. It may also be worth solving #2390 first, and instead add this functionality upstream. (@romancardenas π)
Guard pages are useless if the stack allocation is larger than the guard page itself. A.k.a. the stack clash exploitation, whose mitigation is some sort of stack probing. Basically splitting the allocation into page size wide chunks and doing sw zero, 0(sp) before each. This requires target specific LLVM support, and some enabling in Rust.
Luckily, riscv stack probing has been already been added to LLVM, llvm/llvm-project#117612.
Tracking issue for stack probe support on non-tier-1 targets can be found here rust-lang/rust#43241. And here's an example on how it was added to PowerPC and SystemZ; rust-lang/rust#102328. But due to how it both affects performance, and how it will be enabled in a runtime crate, it would probably need to be passed down as an opt-in compiler flag or the like.
So yeah, what do you think about this so far? Something worth pursuing? Seems like a lot of the groundwork has already been put in place :)
Metadata
Metadata
Assignees
Labels
Type
Projects
Status