A very serious security problem has been found in the Linux kernel. A 0-day local privilege escalation vulnerability has existed for eleven years since 2005. This bug affects all sort of of Android or Linux kernel to escalate privileges. Any user can become root in less than 5 seconds. The bug has existed since Linux kernel version 2.6.22+. How do I fix this problem?

This bug is named as Dirty COW (CVE-2016-5195) is a privilege escalation vulnerability in the Linux Kernel. Exploitation of this bug does not leave any trace of anything abnormal happening to the logs. So you can not detect if someone has exploited this against your server.

What is CVE-2016-5195 bug?

From the project:

A race condition was found in the way the Linux kernel’s memory subsystem handled the copy-on-write (COW) breakage of private read-only memory mappings. 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.

A nasty bug for sure. Any local users can write to any file they can read, and present since at least Linux kernel version 2.6.22. Linus Torvalds explained:

This is an ancient bug that was actually attempted to be fixed once (badly) by me eleven years ago in commit 4ceb5db9757a (“Fix get_user_pages() race for write access”) but that was then undone due to problems on s390 by commit f33ea7f404e5 (“fix get_user_pages bug”).

In the meantime, the s390 situation has long been fixed, and we can now fix it by checking the pte_dirty() bit properly (and do it better). The s390 dirty bit was implemented in abf09bed3cce (“s390/mm: implement software dirty bits”) which made it into v3.9. Earlier kernels will have to look at the page state itself.

Also, the VM has become more scalable, and what used a purely theoretical race back then has become easier to trigger.

To fix it, we introduce a new internal FOLL_COW flag to mark the “yes, we already did a COW” rather than play racy games with FOLL_WRITE that is very fundamental, and then use the pte dirty flag to validate that the FOLL_COW flag is still valid.

A list of affected Linux distros (including VMs and containers that share the same kernel)

  1. Red Hat Enterprise Linux 7.x
  2. Red Hat Enterprise Linux 6.x
  3. Red Hat Enterprise Linux 5.x
  4. CentOS Linux 7.x
  5. CentOS Linux 6.x
  6. CentOS Linux 5.x
  7. Debian Linux wheezy
  8. Debian Linux jessie
  9. Debian Linux stretch
  10. Debian Linux sid
  11. Ubuntu Linux precise (LTS 12.04)
  12. Ubuntu Linux trusty
  13. Ubuntu Linux xenial (LTS 16.04)
  14. Ubuntu Linux yakkety
  15. Ubuntu Linux vivid/ubuntu-core
  16. SUSE Linux Enterprise 11 and 12.
  17. Openwrt

How do I fix CVE-2016-5195 on Linux?

Type the commands as per your Linux distro. You need to reboot the box. Before you apply patch, note down your current kernel version:
$ uname -a
$ uname -mrs

Sample outputs:

Linux 3.13.0-95-generic x86_64

Debian or Ubuntu Linux

$ sudo apt-get update && sudo apt-get upgrade && sudo apt-get dist-upgrade
Reboot the server:
$ sudo reboot

Related: Ubuntu Linux users can hotfix this Linux kernel bug without rebooting the server.

RHEL / CentOS Linux 5.x/6.x/7.x

$ sudo yum update
$ sudo reboot

RHEL / CentOS Linux 4.x

$ sudo up2date -u
$ sudo reboot

Suse Enterprise Linux or Opensuse Linux

To apply all needed patches to the system type:
# zypper patch
# reboot


You need to make sure your version number has changed:
$ uname -a
$ uname -r
$ uname -mrs

Determine if your system is vulnerable

For RHEL/CentOS Linux, use the following script:
$ wget https://access.redhat.com/sites/default/files/rh-cve-2016-5195_2.sh
$ bash rh-cve-2016-5195_2.sh

For all other distro try PoC (proof of concept exploit code)

Grab the PoC:
$ wget https://raw.githubusercontent.com/dirtycow/dirtycow.github.io/master/dirtyc0w.c
Run it as follows. First be root:
$ sudo -s
# echo this is not a test > foo

Run it as normal user:
$ gcc -lpthread dirtyc0w.c -o dirtyc0w
### ***[ If you get an error while compiling code, try ***] ###
$ gcc -pthread dirtyc0w.c -o dirtyc0w
$ ./dirtyc0w foo m00000000000000000
mmap 56123000
madvise 0
procselfmem 1800000000

$ cat foo


🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 30 comments so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf ncdu pydf
File Managementcat tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
30 comments… add one
  • Tom Oct 21, 2016 @ 9:04

    Okay. I need to know when my Android based Verizon phone will be patched?

  • LX500 Oct 21, 2016 @ 9:09

    Wild bug, eh?

    I guess, there is no way to mitigate it without rebooting the box. How about SELinux or grsecurity? It can protect against this kind of bug? Right guys? If not why I should bother with grsecurity or SELinux or apparmor thingy?

    • Famous Oct 21, 2016 @ 10:45

      Because SELinux applies to the filesystem, not memory. COW(copy on write) is a bug in how memory is handled by the kernel. You are basically asking why you need a fire extinguisher when someone can kick down your door and clock you upside the head…

    • eagle1 Oct 21, 2016 @ 11:23

      TPE can protect you from this :)

  • Leo Oct 21, 2016 @ 11:28

    I just update and reboot my centos 7, but the kernel remain the same.
    Is it already patched?

  • Qmpeltaty Oct 21, 2016 @ 11:35

    After running

    After running this command gcc -lpthread dirtyc0w.c -o dirtyc0w, i got error :

    dirtyc0w.c:96:3: warning: format %x expects argument of type unsigned int, but argument 2 has type void * [-Wformat=]
    printf(“mmap %x\n\n”,map);
    /tmp/cc5X5rGq.o: In function `main’:

    • Cristian Oct 21, 2016 @ 18:22

      Since it’s only a warning, it should still generate a binary file. I had some compilation warnings too but it worked nevertheless.

  • Mike Oct 21, 2016 @ 12:51

    Your proof of concept exploit code URL does not work.

  • JohnG Oct 21, 2016 @ 13:40

    Does anyone know the minimum version number of the patched kernel?

    • Ciprian Tomoiag? Oct 22, 2016 @ 14:34

      I think you shouldn’t rely on the minimum version only. For example, under ubuntu and it’s derivatives (linux mint), kernel 3.13 will be patched, because it’s LTS (Long-Term Support) but kernels 3.14-3.19 will be not, because they reached End of Life in August 2016.
      So I would advise you check the support lifetime for your kernel.

  • JasonW Oct 21, 2016 @ 16:47

    This is wrong – just a change of kernel version is not sufficient!

    Patched kernels have not migrated to all mirror sites.

  • Voro Oct 21, 2016 @ 19:55

    Hmmm, I ran

    sudo apt-get update && sudo apt-get upgrade && sudo apt-get dist-upgrade

    but my version (uname -mrs) remains unchanged

    The only thing that’s change is trusty from 14.04.1 to 14.04.5

    p.s. I get the same error trying to compile your dirtyc0w.c

  • Biswajit Oct 21, 2016 @ 20:25

    Even if you update kernel , it is still detecting as vulnerable. Partial mitigation may be a temporary fix but it appears to break syscall.ptrace function!
    My question is the same, do any one have any idea which is the minimum patched kernel version where we can say it is not vulnerable?

  • Bart Oct 22, 2016 @ 7:28

    If the proof-of-concept fails to compile, use -pthread instead of -lpthread.

  • joao.matos Oct 22, 2016 @ 15:06

    there is no update for redhat based distros yet (except for redhat 7)

  • Tomas Oct 24, 2016 @ 10:49

    Various websites (including this one) and news articles simply state that you can protect yourself on RHEL and CentOS by installing the latest updates (yum update; reboot). Which is currently not true, there is no update for RHEL 5 and 6.

  • Nicolas Oct 24, 2016 @ 11:20

    Upgrading your kernel will not fix for Red Hat. See “resolve” tab

    Also rpm -q –changelog kernel | grep -i CVE-2016-5195 , returns an empty query.

  • L C Oct 24, 2016 @ 16:44

    I think it would be helpful to indicate what kind of output from the test indicates a vulnerability, and what kind of output would indicate not being vulnerable.

    For example, here’s my output:

    # ./dirtyc0w foo m00000000000000000
    mmap b76f3000
    madvise 0
    procselfmem -100000000
    root@myhostname:/home/myusername# cat foo
    this is not a test

    I assume this means my system is not vulnerable as the file was not overwritten, but it might be helpful to readers to state explicitly what “I am vulnerable” looks like versus “I am not vulnerable.” My system was not patched, and yet the test looks good, so while I surmise that the above means I am “safe,” it seems strange that an unpatched version would come through as safe.

    • 🐧 Vivek Gite Oct 25, 2016 @ 14:41

      The ./dirtyc0w foo m00000000000000000 must be run as non-root user.

      • L C Oct 25, 2016 @ 16:04

        Thank you Vivek. I get the same results when running as non-root.

        [user@host ~ ] $ ./dirtyc0w foo m00000000000000000
        mmap b76e5000
        madvise 0
        procselfmem -100000000

        [user@host ~ ] $ cat foo
        this is not a test

        My question to the author still stands. It would be helpful to see what the expected output would be for a vulnerable system, *and* the expected output for a non-vulnerable system. I don’t know how to interpret the above. As I said, I can _surmise_ that since the file wasn’t changed, it means I am not vulnerable, but I have not patched my system, and it is not a recently updated debian system.

        • Amila Uduwerella Oct 27, 2016 @ 4:11

          Thanks Vivek for the nice explanation, but I agree with LC as I am also facing the same thing.
          Which is, either I run the command ” ./dirtyc0w foo m00000000000000000 ” as a root or non root user in my non patched system, i cannot see that foo is modified.

        • Sado Oct 28, 2016 @ 19:45

          I think the author simply doesn’t know. He put a general article with no in-depth explanation, plus instructions for patching RHEL/CentOS didn’t work as there was no patch released. I wouldn’t expect any answer.

          • 🐧 Vivek Gite Oct 28, 2016 @ 21:16

            The patch exists for RHEL/CentOS. It was released two days ago.

        • 🐧 Vivek Gite Oct 28, 2016 @ 21:17

          File will not modify if your system is patched. If system is not patched the text ” this is not a test” from foo will be replaced by a dirtyc0w.c running as a non root user. The foo file will look as follows when your run cat foo on affected kernels:

          • L C Oct 28, 2016 @ 22:23

            Vivek, thank you for confirming what I suspected. If the file is not modified, it means the system is not vulnerable. If the file *is* modified, it means the system is vulnerable.

            I was just confused because I know I didn’t patch my system so I thought I must be misreading the output, and since the author didn’t post a positive and negative outcome I wasn’t sure if my assumptions were sound.

            Somehow either my system was patched by someone who is administering the cloud VMs, or my system simply happened to not be vulnerable to this bug (though that seems strange as it is ordinary debian distribution).

            Thanks again.

  • EW Oct 26, 2016 @ 11:35


    I have followed the instructions above and updated my Ubuntu 12.04 system using:

    sudo apt-get update && sudo apt-get upgrade && sudo apt-get dist-upgrade

    I then run the test program, and I am still vulnerable.

    When I run uname -rv I get:
    3.5.0-54-generic #81~precise1-Ubuntu

    So the guys at Ubuntu say I have patched my system however running the test program shows I am still vulnerable.

    Anybody else hit the same issue?

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum