seccomp: require child memory peek in the availability probe
With Yama ptrace_scope=2 and no CAP_SYS_PTRACE, process_vm_readv and /proc/<pid>/mem both fail, so sc_decide cannot read path strings and every workspace write gets EACCES. The old probe only checked the USER_NOTIF round trip, so CST_SANDBOX=seccomp and the forced-seccomp test pass looked available and then failed on the first write. sc_can_peek() forks a child, places a marker on its stack, and retries the same sc_peek path. sc_probe() now needs that too, so those hosts fall back to none (or keep landlock) instead of a silent deny-all sandbox.
This commit is contained in:
+13
-10
@@ -66,16 +66,19 @@ every create / remove / rename / link / chmod / chown / utimes / xattr call
|
||||
stop until the supervisor has read the path from the child's memory,
|
||||
resolved it (cwd, dirfd, `..`, symlinks, `/proc/self`, `/dev/stdout`) and
|
||||
answered: continue when it lands in the allowed places, `EACCES` otherwise.
|
||||
Reads, exec and writes to already-open files are not checked. Background
|
||||
jobs that outlive their shell are no longer the agent's descendants: with
|
||||
Yama `ptrace_scope` ≥ 1 (common on desktop distros, absent on Android) the
|
||||
supervisor cannot read their memory and their checked writes fail with
|
||||
`EACCES`; once the run has finished they get `ENOSYS`. This keeps
|
||||
mistakes out of the rest of the disk but is not a security boundary: the
|
||||
kernel reads the path again after the check, so a hostile multi-threaded
|
||||
program can swap it in between. The availability check runs in a
|
||||
throwaway child, so a platform seccomp policy that kills the caller cannot
|
||||
take the agent down.
|
||||
Reads, exec and writes to already-open files are not checked. The probe also
|
||||
checks that the parent can peek a direct child's memory (`process_vm_readv`
|
||||
or `/proc/<pid>/mem`); with Yama `ptrace_scope=2` and no `CAP_SYS_PTRACE`
|
||||
that fails, so seccomp is not selected (forced `CST_SANDBOX=seccomp` then
|
||||
falls back to unavailable). Background jobs that outlive their shell are no
|
||||
longer the agent's descendants: with Yama `ptrace_scope` ≥ 1 (common on
|
||||
desktop distros, absent on Android) the supervisor cannot read their memory
|
||||
and their checked writes fail with `EACCES`; once the run has finished they
|
||||
get `ENOSYS`. This keeps mistakes out of the rest of the disk but is not a
|
||||
security boundary: the kernel reads the path again after the check, so a
|
||||
hostile multi-threaded program can swap it in between. The availability
|
||||
check runs in a throwaway child, so a platform seccomp policy that kills the
|
||||
caller cannot take the agent down.
|
||||
|
||||
## Terminal notes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user