The fetishism of "byte count" (here, as "732 byte python script") needs to stop, especially when in a context like this where they're trying to illustrate a real failure modality.
Looking at their source code [1] it starts with this simple line:
import os as g,zlib,socket as s
And already I'm perplexed. "os as g"? but we're not aliasing "zlib as z"? Clearly this is auto-generated by some kind of minimizer? Likely because zlib is called only once, and os multiple times. As a code author/reviewer, I would never write "os as g" and I would absolutely never approve review of any code that used this.
Anyway, I could go on. :) Let's just stop fetishizing byte count
Then go on. zlib is only used once, so "zlib as z" in exchange for using z once doesn't get you anything, and then os is used multiple times, so "os as g" is a wash. It's 732 bytes either way.
I don't get the 732-byte thing either and while I think it's a relatively punchy and unusually informative landing page for named vulnerability there are little snags like this all over it.
But the fact that it's not a kernel-exec LPE and it's reliable across kernels and distributions is important; it's close to the maximum "exploitability" you're going to see with an LPE. Which the page does communicate effectively; it just gilds the lily.
I don't see it as fetishizing byte count. I think of it as a proxy measure for how complicated or uncomplicated the exploit might be. They could just as well have said "we can do it in 3 lines of python" or "the Shannon entropy of the script implementing the exploit is really small" and I would have interpreted it similarly.
Where do you see this "fetishizing" happening most often? It's a strange thing to counter-fetishize about.
If you have a choice between posting minimized exploit code, and posting regular exploit code, posting minimized code is virtually always the wrong choice.
If you have a choice between pointing out the byte size of the exploit, and not pointing out the byte size of the exploit, pointing it out is virtually always the wrong choice.
In both cases, doing the right thing is less work. So somebody is going the extra way to ensure they are doing it wrong. If they didn't care, they'd end up doing it right by default.
While not formally reviewing code like this, I read a lot of it for fun. When it's clear and understandable, it's more educational and enjoyable. If the PoC code can also serve as a means of communication, that seems like an extra win.
It seems there was some kind of confusion during the disclosure process, because the vendors aren't treating this vulnerability as serious and it remains unpatched in many distros.
Seems like distros consider it a medium risk because it doesn't involve remote code execution and requires local access. Though it allows local root privilege escalation which is considered high priority.
> Medium: A significant problem, typically exploitable for many users. Includes network daemon denial of service, cross-site scripting, and gaining user privileges.
Strange that it's not classified as "high", which specifically includes "local root privilege escalations".
> High: A significant problem, typically exploitable for nearly all users in a default installation of Ubuntu. Includes serious remote denial of service, local root privilege escalations, local data theft, and data loss.
On the same line it says kernel version 6.12.0-124.45.1.el10_1. Which is RHEL 10. This is the kind of typo that humans make -- the hard to type numbers are accurate because they're cut and pasted, but the "easy" numbers have errors because they're not cut and pasted.
The fact that they have no idea RHEL 14, probably the most well known enterprise distro, is not a thing, and yet they "directly verified on it" casts some doubt on seriousness.
I don't know what to tell you. I'm sure you have them dead to rights on Linux distro knowledge reliability, but the exploit here is real, and the vulnerability researchers they have on staff are also real. Xint is not generally a slop factory.
It's ironic that the one thing LLMs can't do reliably in this space is "write copy for humans" (I don't trust them for that either).
Looks like a LLM hallucination - there is no thing like "RHEL 14.3", although referenced kernel signature (6.12.0-124.45.1.el10_1) contains reference to real RHEL release, i.e. 10.1.
For mitigation, the page currently basically just says:
> Update your distribution's kernel package to one that includes mainline commit a664bf3d603d
But it isn't very clear to me what Kernel version you can expect that to be in. For Arch/CachyOS, the patch seems to be included in 6.18.22+, 6.19.12+ and 7.0+. If you're on any of the lower versions in the same upstream stable series, you're likely vulnerable right now. Some distro kernels may include the fix in other versions, so check for your distribution.
The page itself seems vibecoded and a bit of an advertisement, but it does look like the vulnerability is real and high risk. It does explain the big security update I just got, guess I'll prioritize updating today.
Is there a readable version of the exploit readily available by any chance? Gotta admit that I failed binary-zip-interpretation-with-naked-eye class twice
File "/data/data/com.termux/files/home/a.py", line 5, in c
a=s.socket(38,5,0); # ...
File "/data/data/com.termux/files/usr/lib/python3.13/socket.py", line 233, in __init__
_socket.socket.__init__(self, family, type, proto, fileno)
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 13] Permission denied
I got line 5 to run and failed on line 8 due to lack of su. I'd need to find a user accessible setuid binary for it to work.
Traceback (most recent call last):
File "/data/data/com.termux/files/home/exploit.py", line 8, in <module>
f=g.open("/usr/bin/su",0);i=0;e=zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"))
^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/usr/bin/su'
Now the socket is blocked. Also probably should have realized the socket is defined earlier than its called
Traceback (most recent call last):
File "/data/data/com.termux/files/home/exploit.py", line 9, in <module>
while i<len(e):c(f,i,e[i:i+4]);i+=4
^^^^^^^^^^^^^^^
File "/data/data/com.termux/files/home/exploit.py", line 5, in c
a=s.socket(38,5,0);a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"));h=279;v=a.setsockopt;v(h,1,d('0800010000000010'+'0'64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d('00');u.sendmsg([b"A"4+c],[(h,3,i4),(h,2,b'\x10'+i19),(h,4,b'\x08'+i*3),],32768);r,w=g.pipe();n=g.splice;n(f,w,o,offset_src=0);n(r,u.fileno(),o)
^^^^^^^^^^^^^^^^
File "/data/data/com.termux/files/usr/lib/python3.12/socket.py", line 233, in __init__
_socket.socket.__init__(self, family, type, proto, fileno)
PermissionError: [Errno 13] Permission denied
System partitions being non-writable has nothing to do with the vulnerability - it allows modifying the cache of any file that you can open for reading.
Not using setuid anywhere means you'd have to build a slightly more clever exploit, but it's still trivial - just modify some binary you know will run as root "soon".
But... I didn't check, but IIRC the untrusted_app secontext that apps run in is not allowed to open AF_ALG sockets - so you can't directly trigger the vulnerability as a malicious app. Although it might be possible in some roundabout way (requesting some more privileged crypto service to do so).
Its not writing to the partition though is it? It is polluting the cache page via a write with a buffer overrun in the kernel. I don't think buffer overruns follow permissions.
So this replaces a SUID binary, in order to run as PID 0. The website claims it can escape "Kubernetes / container clusters" and "CI runners & build farms" but I don't see anything supporting the claim it can escape a container (or specifically, a user namespace).
I ran the exploit in rootless Podman, and predictably it doesn't escape the container.
They also claim their script "roots every Linux distribution shipped since 2017.", but only tested four; and it doesn't work on Alpine
>The website claims it can escape "Kubernetes / container clusters" and "CI runners & build farms" but I don't see anything supporting the claim it can escape a container
they state that the write-up is forthcoming. presumably there is some additional steps or modifications that will be detailed in the 'part 2'.
"Next: "From Pod to Host," how Copy Fail escapes every major cloud Kubernetes platform."
It also doesn't work on Raspberry Pi, though presumably it could easily be made to; it does replace the su binary, but the replacement is not executable.
It's patching the binary in memory, so the binary patch would be architecture dependent. The existing one is only x86_64, but with an updated payload, it would work on arm.
If you can get to real UID 0 from a rootless container, you can escape it, but you do need to take extra steps. Same with it working on Alpine: the underlying vulnerability probably still exists, but the script might need some adjusting. It's a PoC, not a full exploit for every situation.
Yes. Alpine in rootless Podman doesn't work (after replacing "/usr/bin/su" with "/bin/su" in the .py, running the .py just doesn't do anything) while it does in Debian in rootless Podman on the same host.
> CVEs are, for whatever reason, like the only thing on the planet that people seem to have a problem with when they receive a name. i am not sure why.
What, you guys talk about books based on their “title” instead of just memorising the ISBN of each book? Pssh, count me disappointed!
Giving catchy names for bad exploits has been a thing for a while. Probably to make sure it's easy to reference and make sure you're patches as opposed to passing numbers around. Heartbleed, Shellshock, BEAST, Goto Fail, etc
It's certainly marketing, but it's prosocial: there's no scarcity of names, and "copy.fail" is much easier to remember and talk about than "CVE-2026-31431".
Probably to some extent it is marketing, but generally it has to do with significant bug finds to get the message out to the people who need to apply patches and/or be informed. Heartbleed, Log4Shell, etc.
Very few CVE’s get names dedicated to them like this, because usually when they do - it is very serious, as in this case.
As of this comment, Debian Stable ("Trixie", though I hate codenames) doesn't have a fix in place and remains vulnerable, or at least their CVE tracker shows it as such:
If this is verified, this is a very big deal. Root access on any shared computer. Additionally do we know what kernel versions and stable versions have the patch?
2026-03-23Reported to Linux kernel security team
2026-03-24Initial acknowledgment
2026-03-25Patches proposed and reviewed
2026-04-01Patch committed to mainline
2026-04-22CVE-2026-31431 assigned
2026-04-29Public disclosure (https://copy.fail/)
kernel 6.19.14-arch1-1, the kernel in question from the parent comment, has been patched.
So this could be usable in lot of places with Python and Linux running? Not that I have too many Linux devices around. Still, might be handy sometimes on personal devices.
Wow. I tried it on an old testing VM of Ubuntu 24.04 that had not been touched for a few months. Instant root with the bonus that any user that runs "su" gets root too.
I updated the VM thinking it would be fixed afterward. Nope.
> If your kernel was built between 2017 and the patch
This is why I compile my own kernel. I disable things I don't use. If it's not present it can't hurt you.
> block AF_ALG socket creation via seccomp regardless of patch state.
Likewise I use seccomp to only allow syscalls that are necessary. Everything else is disabled. In the programs I have that need to connect to a backend socket, that is done, and then socket creation is disabled.
Looking at their source code [1] it starts with this simple line:
import os as g,zlib,socket as s
And already I'm perplexed. "os as g"? but we're not aliasing "zlib as z"? Clearly this is auto-generated by some kind of minimizer? Likely because zlib is called only once, and os multiple times. As a code author/reviewer, I would never write "os as g" and I would absolutely never approve review of any code that used this.
Anyway, I could go on. :) Let's just stop fetishizing byte count
[1] https://github.com/theori-io/copy-fail-CVE-2026-31431/blob/m...
https://gist.github.com/fragmede/4fb38fb822359b8f5914127c2fe...
But the fact that it's not a kernel-exec LPE and it's reliable across kernels and distributions is important; it's close to the maximum "exploitability" you're going to see with an LPE. Which the page does communicate effectively; it just gilds the lily.
Where do you see this "fetishizing" happening most often? It's a strange thing to counter-fetishize about.
How often do you review, and subsequently block the release, of PoCs in this sort of context? Sounds like you've faced this a lot.
I always thought code quality mattered less in those, as long as you communicate the intent.
If you have a choice between pointing out the byte size of the exploit, and not pointing out the byte size of the exploit, pointing it out is virtually always the wrong choice.
In both cases, doing the right thing is less work. So somebody is going the extra way to ensure they are doing it wrong. If they didn't care, they'd end up doing it right by default.
"Just" is doing a lot of work there, I'm so annoyed reading it.
It's like an anti-ad and they had pretty cool material to work with.
* Claude loves stacatto "Some numeric figure. Something else. Intensifier" (ex. the "exploitable for a decade." or whatever sentences)
lucky for them, its an exploit script, not enterprise code.
all that needs to be "reviewed" is whether or not it exploits the thing its supposed to.
https://access.redhat.com/security/cve/cve-2026-31431 "Moderate severity", "Fix deferred"
https://security-tracker.debian.org/tracker/CVE-2026-31431
https://ubuntu.com/security/CVE-2026-31431
https://www.suse.com/security/cve/CVE-2026-31431.html
https://ubuntu.com/security/cves/about#priority
> Medium: A significant problem, typically exploitable for many users. Includes network daemon denial of service, cross-site scripting, and gaining user privileges.
> High: A significant problem, typically exploitable for nearly all users in a default installation of Ubuntu. Includes serious remote denial of service, local root privilege escalations, local data theft, and data loss.
Indeed. "Distributions we directly verified: RHEL 14.3". Directly verified by me to be AI slop (the release page at least).
https://access.redhat.com/articles/red-hat-enterprise-linux-...
> Talk to our security experts
(at the bottom of the page)
I have a sneaking suspicion his first name is Claude. Don't get me wrong though, he is pretty good I hear.
It's ironic that the one thing LLMs can't do reliably in this space is "write copy for humans" (I don't trust them for that either).
> Update your distribution's kernel package to one that includes mainline commit a664bf3d603d
But it isn't very clear to me what Kernel version you can expect that to be in. For Arch/CachyOS, the patch seems to be included in 6.18.22+, 6.19.12+ and 7.0+. If you're on any of the lower versions in the same upstream stable series, you're likely vulnerable right now. Some distro kernels may include the fix in other versions, so check for your distribution.
https://security-tracker.debian.org/tracker/CVE-2026-31431
https://ubuntu.com/security/CVE-2026-31431
Also, disabling algif_aead is suggested as mitigation
> Before you can patch: disable the algif_aead module.
> echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
> rmmod algif_aead 2>/dev/null || true
Edit: and I can confirm that on my system with kernel 6.19.8 the above fixes the exploit.
Traceback (most recent call last): File "/data/data/com.termux/files/home/exploit.py", line 8, in <module> f=g.open("/usr/bin/su",0);i=0;e=zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3")) ^^^^^^^^^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory: '/usr/bin/su'
Traceback (most recent call last): File "/data/data/com.termux/files/home/exploit.py", line 9, in <module> while i<len(e):c(f,i,e[i:i+4]);i+=4 ^^^^^^^^^^^^^^^ File "/data/data/com.termux/files/home/exploit.py", line 5, in c a=s.socket(38,5,0);a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"));h=279;v=a.setsockopt;v(h,1,d('0800010000000010'+'0'64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d('00');u.sendmsg([b"A"4+c],[(h,3,i4),(h,2,b'\x10'+i19),(h,4,b'\x08'+i*3),],32768);r,w=g.pipe();n=g.splice;n(f,w,o,offset_src=0);n(r,u.fileno(),o) ^^^^^^^^^^^^^^^^ File "/data/data/com.termux/files/usr/lib/python3.12/socket.py", line 233, in __init__ _socket.socket.__init__(self, family, type, proto, fileno) PermissionError: [Errno 13] Permission denied
Not using setuid anywhere means you'd have to build a slightly more clever exploit, but it's still trivial - just modify some binary you know will run as root "soon".
But... I didn't check, but IIRC the untrusted_app secontext that apps run in is not allowed to open AF_ALG sockets - so you can't directly trigger the vulnerability as a malicious app. Although it might be possible in some roundabout way (requesting some more privileged crypto service to do so).
~~My allegedly fully patched pixel 8 pro allowed an AF_ALG socket to open under termux without virtualization so I'm not sure the last but is true~~
I ran the exploit in rootless Podman, and predictably it doesn't escape the container.
They also claim their script "roots every Linux distribution shipped since 2017.", but only tested four; and it doesn't work on Alpine
they state that the write-up is forthcoming. presumably there is some additional steps or modifications that will be detailed in the 'part 2'.
"Next: "From Pod to Host," how Copy Fail escapes every major cloud Kubernetes platform."
The details will depend on whether the kernel is a newer release or a maintenance version of an older release.
i bet if i told you their names, you would instantly know what vulns those are.
its easier to talk about things with names. it hurts no one. it takes approximately no effort or time.
CVEs are, for whatever reason, like the only thing on the planet that people seem to have a problem with when they receive a name. i am not sure why.
What, you guys talk about books based on their “title” instead of just memorising the ISBN of each book? Pssh, count me disappointed!
I guess it’s a good thing I’m not a SovCit or I’d just have to call them Traveller Three and Traveller Four
Very few CVE’s get names dedicated to them like this, because usually when they do - it is very serious, as in this case.
Does this mean you can go from a basic web shell from a shared hosting account to root? I can see how that could wreak havoc really quickly.
https://security-tracker.debian.org/tracker/CVE-2026-31431
You can also call it Debian 13.
On this bright side, does this mean Magisk is coming to all unpatched Android phones?
Password: su: Authentication token manipulation error
I'm guessing this means it's already patched?
you are reading about it now because it has been patched.
Ubuntu before 26.04 LTS (released a week ago) are currently listed as vulnerable.
Debian other than forky and sid are currently listed as vulnerable.
This is a disgrace.
This is usable anywhere on an affected Kernel version
> Yes — it's on this page. We held it for a month while distros prepared patches; the major builds are out as of this writing.
There is no update available for Ubuntu 24, PoC works and just tried updating.
This is why I compile my own kernel. I disable things I don't use. If it's not present it can't hurt you.
> block AF_ALG socket creation via seccomp regardless of patch state.
Likewise I use seccomp to only allow syscalls that are necessary. Everything else is disabled. In the programs I have that need to connect to a backend socket, that is done, and then socket creation is disabled.