On Sat, Jan 18, 2025 at 6:25 PM Kees Cook kees@kernel.org wrote:
On January 18, 2025 12:45:47 PM PST, Eyal Birger eyal.birger@gmail.com wrote:
I think the difference is that this syscall is not part of the process's code - it is inserted there by another process tracing it.
Well that's nothing like syscall_restart, and now I'm convinced seccomp must never ignore uretprobe -- a process might want to block uretprobe!
I've been contemplating this. uretprobe is a very odd syscall: it's a syscall that emulates a breakpoint. So, before uretprobe-the-syscall was added, the process would breakpoint via a non-syscall vector, and the tracing code would do its thing, and seccomp would be none the wiser.
There's a distinction between different types of operations that seccomp is entirely unaware of right now: is the task trying to:
a) do something *to itself*
b) do something that doesn't have meaningful side effects on the rest of the world, at least in a non-buggy kernel, but where the process is actually trying to restrict its own actions
c) interacting with something outside the process, that has privilege over the process, where the interaction in question should absolutely be subject to security policy, but that security policy really ought to apply to the outside process.
uretprobe is very much in category c, and it's kind of unique in this sense *as a syscall*. But there are plenty of other examples that just happen to not be syscalls. For example, ptrace breakpoints use the #DB vector, which isn't a syscall.
Here are few factors that may be vaguely relevant:
- uretprobe is conceptually a bit like sigreturn in the sense that both of them are having the kernel help with something that process can kind-of-sort-of do all by itself.
- BUT: sigreturn is not supposed to have side effects reaching outside the calling task. uretprobe does, and that's the whole point.
- uretprobe-the-syscall is, in a rather optimistic sense, obsolete. Once FRED becomes common (if ever...), it won't really serve much purpose any more. FRED, for those not watching, at least in theory, makes "event delivery" and "return" fast, for all (hah!) events. Including breakpoints. And returns to usermode where rcx != rip, etc.
So I don't know what the right answer is. There's a real argument to be made that seccomp ought to decide that its policy permits whomever installed the uretprobe to do so, and that this decision means that the uretprobe machinery is therefore permissible.