Page MenuHomeFreeBSD

Pass the syscall number to capsicum permission-denied signals
Needs ReviewPublic

Authored by theraven on Fri, Jun 4, 11:50 AM.

Details

Reviewers
manu
Summary

This is a back-port of D29185 to 12-STABLE that doesn't modify a field
that is in the middle of struct thread based on kib's suggestion. I
believe the same approach should work for 13-STABLE.

Note that this doesn't bother copying the original_syscall value on
fork. I believe this is fine because the value is only ever accessed
on the return path from failed system calls: if a fork has succeeded,
then the value won't be read until it's been written by the next system
call entry, so it's fine to leave it undefined. Counter examples
welcome in code review!

The syscall number is stored in the same register as the syscall return
on amd64 (and possibly other architectures) and so it is impossible to
recover in the signal handler after the call has returned. This small
tweak delivers it in the si_value field of the signal, which is
sufficient to catch capability violations and emulate them with a call
to a more-privileged process in the signal handler.

Diff Detail

Repository
R10 FreeBSD src repository
Lint
Lint OK
Unit
No Unit Test Coverage
Build Status
Buildable 39699
Build 36588: arc lint + arc unit

Event Timeline

It is not only fork(2) but also rfork(2), which might fail for many reasons.

Can rfork (or pdfork / vfork / whatever) both fail with a capsicum violation *and* create a new struct proc and return in the child context with a signal? That should be the only case where you need to duplicate the original_code field into the child.

  • Use less-ambiguous terminology.

Can rfork (or pdfork / vfork / whatever) both fail with a capsicum violation *and* create a new struct proc and return in the child context with a signal? That should be the only case where you need to duplicate the original_code field into the child.

Might be not, but you are putting very un-obvious landmine for an un-initiated there. Even if you consider *fork(2) failure in this mode unlikely, somebody could end up with a different use for the syscall number, and it would silently fail for forks on stable branches.