
# CVE-2026-31429 के लिए POC (Linux Kernel >= 6.3 < 6.12.82 Slab Cross-Cache Confusion) - एंटोनियस - w1sdom - bluedragonsec.com द्वारा खोजी गई भेद्यता
bpf_prog_test_run_skb के माध्यम से KFENCE-आवंटित SKB हेड का क्रॉस-कैश फ्रीगंभीरता: मध्यम (CWE-763: अमान्य पॉइंटर या संदर्भ का रिलीज़)
प्रकाशित: 2026-04-20
प्रभावित सबसिस्टम: net/core/skbuff.c — skb_kfree_head()
शोधकर्ता: Antonius / w1sdom — Blue Dragon Security
संपर्क: [email protected]
Lore थ्रेड: https://lore.kernel.org/netdev/CAK8a0jxC5L5N7hq-DT2_NhUyjBxrPocoiDazzsBk4TGgT1r4-A@mail.gmail.com/
इस रिपॉजिटरी में CVE-2026-31429 के लिए proof-of-concept शामिल है (कार्यशील एक्सप्लॉइट नहीं, केवल POC), जो Linux कर्नेल नेटवर्किंग स्टैक में एक slab क्रॉस-कैश कन्फ्यूजन बग है। यह बग तब ट्रिगर होता है जब KFENCE सक्षम होता है और एक कॉलर (विशेष रूप से net/bpf/test_run.c में bpf_test_init) kzalloc() के माध्यम से एक SKB हेड बफर आवंटित करता है, जिसका आकार संयोगवश SKB_SMALL_HEAD_CACHE_SIZE के बराबर होता है। KFENCE की सटीक-आकार रिपोर्टिंग सेमेन्टिक्स के कारण, कर्नेल का skb_kfree_head() फ़ंक्शन ऑब्जेक्ट को मूल kmalloc-1k कैश के बजाय गलती से skb_small_head_cache में वापस फ्री कर देता है, जिससे slab मेटाडेटा दूषित हो जाता है।
| स्थिति | रेंज |
|---|---|
| प्रभावित | Linux >= 6.3 (bf9f1baa279f द्वारा पेश किया गया) |
| अप्रभावित | < 6.3 |
| ठीक किया गया | >= 6.12.82 |
| ठीक किया गया | >= 6.18.23 |
| ठीक किया गया | >= 6.19.13 |
| ठीक किया गया | >= 7.0 (मेनलाइन, कमिट 0f42e3f4fe2a) |
यह भेद्यता कमिट bf9f1baa279f ("net: add dedicated kmem_cache for typical/small skb->head") द्वारा पेश की गई थी, जिसने skb_small_head_cache और skb_kfree_head() में कंडीशनल फ्री लॉजिक जोड़ा।
skb_small_head_cache डिज़ाइन उद्देश्यSKB_SMALL_HEAD_CACHE_SIZE को जानबूझकर गैर-पावर-ऑफ-2 मान (जैसे x86_64 पर 704 बाइट्स) पर सेट किया गया है, ताकि सामान्य kmalloc बकेट आकारों (हमेशा 2 की घातें: 512, 1024, ...) के साथ टकराव से बचा जा सके। skb_kfree_head() में ह्यूरिस्टिक केवल skb_end_offset का उपयोग करके फ्री को रूट करने के लिए इस विशिष्टता का फायदा उठाता है:
// net/core/skbuff.c (कमजोर — फिक्स से पहले)
static void skb_kfree_head(void *head, unsigned int end_offset)
{
if (end_offset == SKB_SMALL_HEAD_HEADROOM)
kmem_cache_free(net_hotdata.skb_small_head_cache, head);
else
kfree(head);
}
end_offset == SKB_SMALL_HEAD_HEADROOM → skb_small_head_cache से माना गया → kmem_cache_free()kfree()यह ह्यूरिस्टिक केवल सामान्य slab सेमेन्टिक्स के तहत सही है, जहां ksize() बकेट आकार लौटाता है (704-बाइट अनुरोध के लिए 1024), जो कभी भी SKB_SMALL_HEAD_CACHE_SIZE के बराबर नहीं होता।
KFENCE (Kernel Electric-Fence) कर्नेल आवंटनों के एक सबसेट को इंटरसेप्ट करता है और उन्हें गार्ड-पेज्ड मेमोरी से सेवा प्रदान करता है। इसका महत्वपूर्ण व्यवहारिक अंतर: kfence_ksize() सटीक अनुरोधित आकार लौटाता है, न कि slab बकेट आकार।
BPF_PROG_TEST_RUN (syscall 321, cmd BPF_PROG_TEST_RUN=10)
└─> __sys_bpf()
└─> bpf_prog_test_run_skb()
└─> bpf_test_init()
└─> kzalloc(size, GFP_USER)
│ size == SKB_SMALL_HEAD_CACHE_SIZE (x86_64 पर 704)
│ KFENCE इंटरसेप्ट करता है → ऑब्जेक्ट kmalloc-1k क्षेत्र से सेवा प्राप्त करता है
│
└─> slab_build_skb(data, NULL, size)
└─> ksize(data)
└─> kfence_ksize() ← 704 लौटाता है (सटीक!)
└─> skb_end_offset
= ksize(data) - sizeof(skb_shared_info)
= 704 - 320
= 384
= SKB_SMALL_HEAD_HEADROOM ← गलत मिलान!
[SKB फ्री पथ पर:]
└─> sk_skb_reason_drop()
└─> skb_release_data()
└─> skb_free_head()
└─> skb_kfree_head(head, skb->end)
└─> (end_offset == SKB_SMALL_HEAD_HEADROOM) == TRUE
└─> kmem_cache_free(skb_small_head_cache, head)
↑ BUG: head kmalloc-1k से है, skb_small_head_cache से नहीं!
→ warn_free_bad_obj() → SLUB भ्रष्टाचार
skb_end_offset = 384 क्यों?x86_64 पर:
SKB_SMALL_HEAD_CACHE_SIZE = 704 बाइट्स
sizeof(skb_shared_info) = 320 बाइट्स
SKB_SMALL_HEAD_HEADROOM = 704 - 320 = 384
जब KFENCE 704-बाइट kzalloc() को इंटरसेप्ट करता है, तो kfence_ksize() बिल्कुल 704 लौटाता है। अंकगणित skb_end_offset = 384 = SKB_SMALL_HEAD_HEADROOM उत्पन्न करता है, जो skb_kfree_head() में कंडीशन को संतुष्ट करता है — गलत फ्री पथ को ट्रिगर करता है।
Jiayuan Chen द्वारा अपस्ट्रीम फिक्स (Eric Dumazet द्वारा समीक्षित, Jakub Kicinski द्वारा मर्ज) ह्यूरिस्टिक को पूरी तरह से समाप्त कर देता है:
// net/core/skbuff.c (ठीक किया गया)
static void skb_kfree_head(void *head, unsigned int end_offset)
{
kfree(head); // हमेशा सामान्य; दोनों मामलों के लिए काम करता है
}
kfree() kmalloc-आवंटित और skb_small_head_cache-आवंटित दोनों मेमोरी के लिए सुरक्षित है क्योंकि skb_small_head_cache पर kmem_cache_free() अब आवश्यक नहीं है — सामान्य kfree() slab पेज के kmem_cache पॉइंटर के माध्यम से आंतरिक रूप से सही कैश का समाधान करता है।
रीप्रोड्यूसर (repro_bpf.c) को QEMU वातावरण (i440FX, BIOS 1.17.0-debian) में Linux 7.0.0-rc5 पर चलाया गया था। निम्नलिखित कर्नेल WARNING कैस्केड देखा गया:
[ 3065.322973] ------------[ cut here ]------------
[ 3065.322990] kmem_cache_free(skbuff_small_head, ffff888186d6e000): object belongs to different cache kmalloc-1k
[ 3065.323005] WARNING: mm/slub.c:6258 at warn_free_bad_obj+0x91/0xc0, CPU#0: repro_bpf/2167
[ 3065.323061] CPU: 0 UID: 0 PID: 2167 Comm: repro_bpf Not tainted 7.0.0-rc5 #1 PREEMPT(lazy)
[ 3065.323098] RIP: 0010:warn_free_bad_obj+0x98/0xc0
...
[ 3065.323231] Call Trace:
[ 3065.323247] skb_free_head+0x1ec/0x290
[ 3065.323267] skb_release_data+0x7a6/0x9d0
[ 3065.323308] bpf_prog_test_run_skb+0x14f8/0x3410
[ 3065.323510] __sys_bpf+0x769/0x4b60
[ 3065.323763] __x64_sys_bpf+0x78/0xc0
[ 3065.323794] do_syscall_64+0x111/0x690
[ 3065.323813] entry_SYSCALL_64_after_hwframe+0x77/0x7f
WARNING कैस्केड प्रति ट्रिगर 4 अलग-अलग splats उत्पन्न करता है:
warn_free_bad_obj — प्राथमिक क्रॉस-कैश फ्री डिटेक्शन (mm/slub.c:6258)depot_fetch_stack — स्टैक डिपो पूल इंडेक्स सीमा से बाहर (lib/stackdepot.c:506) Allocated ट्रैकिंग परstack_depot_print — भ्रष्ट हैंडल का पता चला (lib/stackdepot.c:780)depot_fetch_stack + stack_depot_print — Freed ट्रैकिंग के लिए वही जोड़ी दोहराई गईयह कैस्केड इंगित करता है कि ऑब्जेक्ट का SLUB ट्रैकिंग मेटाडेटा (alloc_track / free_track) एक स्टैक डिपो हैंडल को संदर्भित करता है जो गलत-कैश फ्री के बाद भ्रष्ट हो जाता है।
कर्नेल: Linux >= 6.3, निम्न के साथ संकलित:
CONFIG_KFENCE=y
CONFIG_BPF_SYSCALL=y
CONFIG_NET_SCH_INGRESS=y (या कोई भी SCHED_CLS सक्षम ड्राइवर)
CONFIG_SLUB_DEBUG=y (warn_free_bad_obj दृश्यता के लिए)
CONFIG_STACKDEPOT=y (पूर्ण कैस्केड के लिए)
विशेषाधिकार: root (uid=0) — BPF_PROG_LOAD के लिए आवश्यक
gcc -O2 -o cve-2026-31429-poc-only cve-2026-31429-poc-only.c
sudo ./cve-2026-31429-poc-only
dmesg | grep -E "warn_free_bad_obj|Wrong slab cache|cross-cache"
PoC एक न्यूनतम 3-निर्देश BPF प्रोग्राम लोड करता है (प्रकार BPF_PROG_TYPE_SCHED_CLS):
ld_imm64 r0, 0 ; 2 insns (wide)
exit ; 1 insn
फिर यह BPF_PROG_TEST_RUN (cmd=10) को निम्न के साथ कॉल करता है:
data_size_in = 284 बाइट्स Syzkaller-व्युत्पन्न पैकेट डेटाflags = BPF_F_TEST_RUN_ON_CPU (0x4) — निष्पादन को CPU 0 पर पिन करता हैrepeat = 4284-बाइट इनपुट डेटा bpf_test_init के आवंटन पथ का उपयोग करता है ताकि अनुरोधित बफर आकार SKB_SMALL_HEAD_CACHE_SIZE के बराबर हो, संभावित रूप से KFENCE इंटरसेप्शन विंडो को हिट करता है।
| कमिट | ट्री | मर्जकर्ता | तिथि |
|---|---|---|---|
0f42e3f4fe2a | मेनलाइन | Jakub Kicinski | 2026-04-06 |
60313768a8ed | linux-stable | Greg Kroah-Hartman | 2026-04-18 |
2d64618ea846 | linux-stable | Greg Kroah-Hartman | 2026-04-18 |
474e00b935db | linux-stable | Greg Kroah-Hartman | 2026-04-18 |
Signed-off श्रृंखला: Jiayuan Chen → Reviewed-by Eric Dumazet (Google) → Jakub Kicinski → Greg Kroah-Hartman
Reported-by क्रेडिट: सभी 4 कमिटों में Antonius <[email protected]>
द्वारा पेश किया गया: bf9f1baa279f ("net: add dedicated kmem_cache for typical/small skb->head")
.
├── README.md — यह फ़ाइल
├── cve-2026-31429-poc-only.c — केवल proof-of-concept (एक्सप्लॉइट नहीं)
└── dmesg.txt — सफल पुनरुत्पादन से कच्चा कर्नेल splat
| तिथि | घटना |
|---|---|
| ~2026 की शुरुआत | Linux 7.0-rc5 पर Syzkaller फज़िंग के माध्यम से बग की खोज |
| 2026-04-03 | Jiayuan Chen द्वारा पैच लिखा गया, Reported-by क्रेडिट Antonius को |
| 2026-04-06 | मेनलाइन कमिट 0f42e3f4fe2a Jakub Kicinski द्वारा मर्ज |
| 2026-04-18 | Greg Kroah-Hartman द्वारा स्टेबल बैकपोर्ट मर्ज (6.12.x, 6.18.x, 6.19.x) |
| 2026-04-20 | CVE-2026-31429 प्रकाशित |
Antonius (उपनाम: w1sdom)
संस्थापक और वरिष्ठ शोधकर्ता — Blue Dragon Security
इंडोनेशिया
[email protected]
यह PoC अपस्ट्रीम पैच उपलब्ध होने के बाद शैक्षिक और शोध उद्देश्यों के लिए जारी किया गया है। उन सिस्टमों पर उपयोग न करें जिनके आप स्वामी नहीं हैं या जिनके परीक्षण की स्पष्ट अनुमति आपके पास नहीं है। लेखक दुरुपयोग के लिए कोई जिम्मेदारी नहीं लेता है।