Linux af_packet.c race condition local root exploit(seclists.org)
seclists.org
Linux af_packet.c race condition local root exploit
http://seclists.org/oss-sec/2016/q4/607
24 comments
http://kernsec.org/wiki/index.php/Kernel_Self_Protection_Pro... provides a good list.
Awesome, thanks. I had heard of the kernel self protection project, but didn't realise that they'd also maintain such a nice list :-)
Or you can use grsecurity, which goes even further: https://grsecurity.net/
In fact, many of the KSP patches are inspired by Grsecurity.
In fact, many of the KSP patches are inspired by Grsecurity.
Would this vulnerability have been mitigated with default grsec, ooi?
Not sure about this one but there has been more than enough public vulns that grsec was already protecting against before release to justify using it for the security conscious Linux user.
Archlinux has packages that make it very easy to use.
Archlinux has packages that make it very easy to use.
Note that if you can compile the kernel yourself there are benefits to doing so. It's been a while so I forget the details but grsecurity uses some randomization at compile time, and an attacker with access to the public image would be able to get around those defenses. If you own the seed, and delete it after compilation, an attacker will not be able to bypass those defenses.
Naturally you still benefit a ton without those, but the ideal situation involves compiling it.
Naturally you still benefit a ton without those, but the ideal situation involves compiling it.
Grsecurity does not allow unprivileged namespaces, so this would only be exploitable by a root user.
According to https://security-tracker.debian.org/tracker/CVE-2016-8655
"Non-privileged user namespaces disabled by default, only vulnerable with sysctl kernel.unprivileged_userns_clone=1"
But: ... on systems where unprivileged namespaces are enabled (Ubuntu, Fedora, etc).
Interesting that Ubuntu and Debian differ here.
As of right now it doesn't appear that any distribution has fixed this yet, which is odd since it was fixed upstream a week ago.
"Non-privileged user namespaces disabled by default, only vulnerable with sysctl kernel.unprivileged_userns_clone=1"
But: ... on systems where unprivileged namespaces are enabled (Ubuntu, Fedora, etc).
Interesting that Ubuntu and Debian differ here.
As of right now it doesn't appear that any distribution has fixed this yet, which is odd since it was fixed upstream a week ago.
Also, be careful about turning that off on Ubuntu if using Canonical's live patching - that is built on snaps and requires user namespaces.
It has been fixed in Ubuntu and OpenVZ:
https://www.ubuntu.com/usn/usn-3151-1/
https://virtuozzo.com/linux-kernel-security-exploit-fix/
https://www.ubuntu.com/usn/usn-3151-1/
https://virtuozzo.com/linux-kernel-security-exploit-fix/
In Virtuozzo at least. They don't mention OpenVZ.
As many people found out with Dirty COW, the latest version of OpenVZ doesn't receive tested patched kernels in response to newly discovered bugs. Their options are to run a nightly kernel build or to pay for Virtuozzo for their 'ReadyKernel' patches:
"Virtuozzo team uploads stable kernels for OpenVZ version 7, tested for our commercial customers, approximately once a quarter. In between, we do not test or release any kernels - all the intermediate updates are delivered to our commercial customers in rebootless (kpatch) format without building full kernel updates. Again, this is a part of our commercial offering.
As for the contributions to the community product, we still build these kernels for the "factory" repository. However, we are not equipped to test them on regular basis, between these quarterly updates."
"Virtuozzo team uploads stable kernels for OpenVZ version 7, tested for our commercial customers, approximately once a quarter. In between, we do not test or release any kernels - all the intermediate updates are delivered to our commercial customers in rebootless (kpatch) format without building full kernel updates. Again, this is a part of our commercial offering.
As for the contributions to the community product, we still build these kernels for the "factory" repository. However, we are not equipped to test them on regular basis, between these quarterly updates."
I believe something similar to this also affected systrace, leading to its deprecation. Are there any tools that can catch this sort of thing, or is it too dependent on the intent of the programmer/API designer? Maybe it's possible to have a heuristic "other uses of this structure take a lock, but this one doesn't"?
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.
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.
I hope someone builds an exploiter for this on Android soon - I upgraded too fast to the latest security release :/
I doubt android kernels have unprivileged namespaces enabled.
Normal android apps don't have permission to send raw packets.
To quote the mail:
> On Android, processes with gid=3004/AID_NET_RAW are able to create AF_PACKET sockets (mediaserver) and can trigger the bug.
I believe that this is the Android permission android.permission.NET_ADMIN, so it should work in theory...
> On Android, processes with gid=3004/AID_NET_RAW are able to create AF_PACKET sockets (mediaserver) and can trigger the bug.
I believe that this is the Android permission android.permission.NET_ADMIN, so it should work in theory...
I don't know what permission it is, but I know that there is no permission that Play Store apps can have that allows sending raw packets. There's an open bug about it on the AOSP bug tracker.
System apps can obviously do it - hence the "(mediaserver)" comment.
System apps can obviously do it - hence the "(mediaserver)" comment.
I only see a fix for Ubuntu 16.04, does that mean that 14.04 isn't vulnerable?
Ubuntu 12.04 and 14.04 are vulnerable too, here are the notices:
https://www.ubuntu.com/usn/usn-3150-1/
https://www.ubuntu.com/usn/usn-3149-1/
https://www.ubuntu.com/usn/usn-3150-1/
https://www.ubuntu.com/usn/usn-3149-1/
Thanks!
Looking forward to today's server patching...
I wonder if I get it right, in order to exploit the vulnerability, an unprivileged user must be able to create network namespaces, so he will be able to create raw sockets?
Does anyone know where to find more advice like this? Which features of the kernel to disable in order to be more secure?