News for hackers. Stuff that matters.
Re:Linux af_packet.c race condition local root exploit by wahern on Tuesday December 06, 2016 @03:27PM (#13117989)
Race conditions are a large class of issues.

The race in systrace was that non-scalar syscall arguments (e.g. file path strings) were not copied into kernel space before running the policy checks. That meant that a malicious process could alter a string argument (e.g. from another thread) after the systrace check but before the syscall routine actually used the argument. It was a well-known issue with systrace, but systrace worked well other than that. (And, arguably, even with the race it still provided a worthwhile mitigation as long as it was understood it wasn't bulletproof for non-scalar values.)

Copying non-scalar arguments into kernel buffers was considered too costly. I don't even think OpenBSD bothered doing it, and certainly Linux didn't as systrace was an out-of-tree patch. OpenBSD's pledge framework does have the ability to verify some string arguments (e.g. paths to open), which of course necessitates first copying them into kernel space. (Or, at least, for certain strings, such as "/etc/passwd", replacing the argument with an in-kernel address.)

Linux seccomp is very similar to systrace. Rather than addressing the race wrt non-scalar arguments, seccomp simply doesn't allow you to check the value of non-scalar arguments. So, for example, you cannot write a seccomp policy that can directly check the path argument to open.[1]

[1] You can, however, write a string to a mmap'd region, make the region read-only, load seccomp policies that prevent changing the flags of that region (e.g. a policy checking the address ranges of mmap, madvise, etc). Then when you use wish to pass a particular string value to a syscall that is whitelisted by a seccomp policy, you lookup the string in the protected region and pass a pointer to _that_ string if it exists. Then the seccomp policy can verify the _address_ of the string knowing that [theoretically] the object it points to is immutable. It's all very convoluted and brittle, though. And it also makes it difficult to emulate OpenBSD pledge on Linux.[2] You'd have to interpose the libc syscall wrappers to looking string arguments in the protected region.

[2] The other issue is that pledges aren't inherited across fork while seccomp policies are always inherited, which means you definitely cannot emulate pledge on Linux if you allow forking.

There are no comments on this comment yet.