CTSRD-CHERI / cheribsd

FreeBSD adapted for CHERI-RISC-V and Arm Morello.
http://cheribsd.org
Other
157 stars 58 forks source link

Signal handler error in riscv-hybrid sandbox #2098

Open mahiru23 opened 2 months ago

mahiru23 commented 2 months ago

I'm using riscv-hybrid-cap, where my thread runs in a sandbox with isolation boundaries like this:

pcc            0x11172000000100060000000400004b7e       0x400004b7e [rxR,0x400000000-0x440000000]
ddc            0x117d0000000100060000000400000000       0x400000000 [rwRW,0x400000000-0x440000000]

I registered a signal handler for working thread to receive and handle SIGALRM signals periodically sent by a timer. The signal handler works well outside the sandbox, but when the thread enters the sandbox via cinvoke, it encounters an error when trying to receive signals in cheribsd/sys/riscv/riscv/freebsd64_machdep.c function freebsd64_sendsig() like this:

pid 819, tid 100067: could not copy out cap registers

I attempted to use an alternative stack with sigaltstack(), however it didn't resolve the issue. I'm unsure about the execution logic of copyoutcap in this process, but it seems to crash at this point.

Personally, I believe that the signal stack after entering freebsd64_sendsig() is somewhat untrusted, but I'm unable to pinpoint the issue more granularly. Anyone can provide some helps or some possible attempts? Thank you.

jrtc27 commented 2 months ago

Your problem is there's no way to configure what DDC should be for a signal handler, and since you're using hybrid the pointers you provide to the kernel for the stack and function to run are integer addresses. I don't think we have any way to make this work currently, but in general sandboxing with hybrid is a world of pain anyway.

jrtc27 commented 2 months ago

(Though we're a bit inconsistent; for the function pointer we inherit PCC's metadata at the time of the sigaction call, but for the stack pointer we inherit DDC's metadata at the time of signal delivery)

jrtc27 commented 2 months ago

See also #1315