2 ms·
Linux pledge is built on top of seccomp, which by default only applies a newly added filter to the current thread, and copies it to all future threads cloned fr
by LegionMammal978 3y ago
Linux pledge is built on top of seccomp, which by default only applies a newly added filter to the current thread, and copies it to all future threads cloned from the current thread. There exists a flag (SECCOMP_FILTER_FLAG_TSYNC) to automatically copy the filter to all other threads of the current process, but the pledge library does not set this flag.
If the flag were used, then each thread's filter tree would be atomically swapped out from its old version, then the thread would be set to be in SECCOMP_MODE_FILTER if it isn't already. Setting the mode causes the SYSCALL_WORK_SECCOMP bit to be set in the thread's syscall_work field, which the thread checks every time it enters a syscall from user mode. Therefore, any currently-running syscall in the thread may or may not go through, but all future syscalls will be subject to the new filter.
If current long-running syscalls are a concern, then I think (but haven't tested) it would be sufficient to define a signal handler without SA_RESTART, then send the corresponding signal to every other thread to interrupt all their syscalls. The handler could even have a counter that gets incremented so that the caller knows when all threads have been interrupted; this is basically how libcs implement a process-wide setuid/setgid on top of Linux's per-thread syscalls.