Here comes what we’re calling a bus-scenario BWAIN.
DirtyCOW, as it’s been satirically dubbed, is a kernel bug in Linux that’s been around for at least 11 years and as good as allows any existing user to turn themselves into the all-powerful system administrator known in the Linux world as root.
To explain: a bus scenario is where you don’t hear much about a particular security topic for a while, and then it comes up twice in quick succession, like those proverbial buses that keep you waiting for ages and then arrive in a bunch.
And COW is short for Copy On Write, a time-saving trick that most modern operating systems use so that when you copy something (a file, for example, or a block of memory), you don’t actually get a copy right away.
You just get carefully-regulated access to the original item, until someone changes it; only then does the copy really happen, because only then are there two distinct versions that need to diverge.
Of course, if there’s a glitch in the COW mechanism, and the copy doesn’t happen when it should, or happens when it shouldn’t, changes can be lost, or applied in the wrong place.
If you’re a techie, you may well be satisfied with this explanation:
A race condition was found in the way Linux kernel’s memory subsystem handled breakage of the read only private mappings COW situation on write access.
An unprivileged local user could use this flaw to gain write access to otherwise read only memory mappings and thus increase their privileges on the system.
The COW situation
We found the jargon “breakage of the COW situation” a touch confusing, so we decided to dig a bit further.
For better or worse, there’s a proof-of-concept (PoC) program already available that demonstrates the bug in action.
We used the PoC to learn if and how this vulnerability could be exploited; we found that it could, rather easily and very quickly. (We used a not-yet-patched 32-bit 4.4.19 Linux kernel, for what that’s worth.)
The PoC works roughly like this:
1. Map your own process memory into what’s known as a writeable private mapping.
COW, of course, means that you don’t actually get a copy right away.
Nevertheless, you can change this memory at will whenever you want, without affecting your own running program, because any modifications to a private map don’t “shine through” into the underlying process memory.
2. Map into memory a file to which you have read-only access.
In theory, COW ought to be irrelevant here: you don’t have write access to the file, so you don’t have write access to the memory map, so you shouldn’t be able to change it at all.
3. Fire up two parallel threads of execution.
One thread hammers away writing changes into the writeable private map; the other hammers away telling the kernel it can temporarily free up any memory used for the mapped file.
A race condition
Due to CVE-2016-5195, the two threads hammering away at the two memory maps will soon experience some sort of access collision – what’s known in the jargon as a race condition – and the data you’re trying to write into the private memory map will accidentally be dumped into the memory map of the read-only file instead.
Unfortunately, the main idea of a memory-mapped file is programmatic convenience: changes written into the memory map are immediately and automatically reflected in the actual file on disk.
Obviously, that’s not supposed to happen because you only have read access to the file’s memory map, and you have no privilege to write to the file itself.
The result is a security SNAFU: a regular user can permanently tamper with system files that would usually require a root login to modify.
That could include important configuration files like
ssh_config, private cryptographic keys, or even system software such as the
/bin/login program itself.
Ironically, perhaps, this bug was first addressed eleven years ago by Linus Torvalds himself, but the fix back then was removed because it caused problems on the IBM mainframe version of Linux.
What Linus describes as a merely “theoretical” bug back then has ended up perfectly practical today:
This is an ancient bug that was actually attempted to be fixed once (badly) by me eleven years ago […] but that was then undone due to problems on s390… [W]hat used a purely theoretical race back then has become easier to trigger.
What to do?
This bug doesn’t provide a way for an outsider to break into your system in the first place, so it’s not what we call a remote code execution (RCE) hole.
DirtyCOW is an EoP vulnerability, short for elevation of privilege.
Nevertheless, as we explained above, attackers who are already inside your network are likely to find this a handy way of extending their reach.
A patch is already available.
If you are an intrepid Linux user you can apply the patch yourself and rebuild your kernel.
If not, watch out for the next kernel update from your distro producer and apply it as soon as you can.