
pedit COW
CVE-2026-46331 (उपनाम “pedit COW”) ट्रैफ़िक-नियंत्रण सबसिस्टम में एक स्थानीय Linux कर्नेल विशेषाधिकार-वृद्धि दोष है। एक विशेषाधिकार-रहित उपयोगकर्ता (विशेषाधिकार-रहित नेटवर्क नेमस्पेस में) act_pedit (पैकेट संपादक) फ़िल्टर को कॉन्फ़िगर करके पेज कैश में आंशिक कॉपी-ऑन-राइट (COW) लेखन ट्रिगर कर सकता है। प्रभावी रूप से, कर्नेल पृष्ठ को निजी चिह्नित किए बिना हमलावर-नियंत्रित डेटा को फ़ाइल की इन-मेमोरी छवि में लिखता है, जिससे उस फ़ाइल की कैश्ड प्रतिलिपि दूषित हो जाती है। महत्वपूर्ण बात यह है कि इस शोषण के लिए केवल CAP_NET_ADMIN की आवश्यकता होती है (जो उपयोगकर्ता नेमस्पेस में प्राप्त किया जा सकता है) और यह डिस्क पर मौजूद फ़ाइल को संशोधित नहीं करता। व्यवहार में, packet_edit_meme नामक एक कार्यशील प्रूफ-ऑफ-कॉन्सेप्ट (PoC) 17 जून, 2026 को प्रकाशित किया गया था, जो दर्शाता है कि रूट शेल प्राप्त करने के लिए setuid बाइनरी (जैसे /bin/su) की पेज-कैश छवि को कैसे अधिलेखित किया जाए। यह भेद्यता tcf_pedit_act() में गलत COW-सीमा गणना से उत्पन्न होती है और इसे अपस्ट्रीम (4 जून, 2026) में प्रति-कुंजी लूप में राइटेबल-क्षेत्र जाँच को स्थानांतरित करके ठीक किया गया है।
act_pedit है। बिना पैच वाले स्थिर रिलीज़ (कई डिस्ट्रो कर्नेल सहित) असुरक्षित हैं।tc pedit फ़िल्टर सेट करता है, और मेमोरी में setuid बाइनरी के ELF एंट्री पॉइंट को शेलकोड से अधिलेखित कर देता है।skb_ensure_writable() को कुंजी लूप के अंदर स्थानांतरित कर दिया)। वर्कअराउंड के रूप में, act_pedit मॉड्यूल को ब्लॉक या अनलोड करें या विशेषाधिकार-रहित उपयोगकर्ता नेमस्पेस को अक्षम करें (जैसे sysctl user.max_user_namespaces=0). शमन के बाद, कैश ड्रॉप करें (echo 3 > /proc/sys/vm/drop_caches) ताकि किसी भी विषाक्त पृष्ठ को हटाया जा सके।यह रिपोर्ट CVE-2026-46331 का विस्तृत तकनीकी विश्लेषण प्रदान करती है: इसका कारण, शोषण, पहचान और उपचार रणनीतियाँ, विक्रेता सलाह, CVE और सार्वजनिक शोषण के संदर्भों के साथ।
परिभाषा: CVE-2026-46331 Linux कर्नेल के ट्रैफ़िक नियंत्रण (net/sched) सबसिस्टम में एक आउट-ऑफ-बाउंड राइट बग है, विशेष रूप से act_pedit (पैकेट संपादक) क्रिया में। फ़ंक्शन tcf_pedit_act() टाइप की गई कुंजियों पर पुनरावृति करने से पहले पैकेट-संपादन कार्यों के लिए एक “कॉपी-ऑन-राइट” सीमा की गणना करता है, एक स्थिर संकेत tcfp_off_max_hint का उपयोग करते हुए। हालाँकि, कुछ कुंजियाँ (जैसे TCP/UDP हेडर संपादन) अपने अंतिम बाइट ऑफ़सेट का निर्धारण केवल रनटाइम पर करती हैं। कोड इन गतिशील ऑफ़सेट के लिए कभी भी राइटेबिलिटी की पुनः जाँच नहीं करता। परिणामस्वरूप, लेखन पूर्व-COW’d क्षेत्र के बाहर हो सकता है: पैकेट लेखन का कुछ भाग कभी निजी नहीं बनाया जाता, जिससे आंशिक COW उत्पन्न होता है। यह त्रुटिपूर्ण लेखन किसी फ़ाइल की साझा पेज-कैश मेमोरी में फैल जाता है (यदि पैकेट बफ़र संयोगवश फ़ाइल पृष्ठों को संदर्भित करते हैं), जिससे कैश्ड फ़ाइल छवि दूषित हो जाती है।
पृष्ठभूमि: Linux पैकेट संपादक (pedit) क्रिया प्रशासकों को कॉन्फ़िगर किए गए tc फ़िल्टर से गुजरते समय पैकेट हेडर (लिंक, नेटवर्क, या ट्रांसपोर्ट परतों) के भीतर स्वेच्छ बाइट्स को फिर से लिखने की अनुमति देती है। यह एक ऑफ़सेट (संभवतः किसी हेडर से जुड़ा हुआ) और एक 32-बिट मान/मास्क निर्दिष्ट करके काम करती है। आंतरिक रूप से, pedit सॉकेट-बफ़र्स (sk_buff) पर संचालित होता है और इसे संशोधित करने से पहले लक्षित पैकेट मेमोरी को राइटेबल बनाना होता है (skb_ensure_writable() के माध्यम से COW शैली में)। आदर्श रूप से, कर्नेल को लेखन से पहले किसी भी साझा पृष्ठ को क्लोन (निजी-प्रतिलिपि) करना चाहिए ताकि अन्यत्र उपयोग की जा रही मेमोरी को बदलने से बचा जा सके।
मूल कारण: tcf_pedit_act() में, कोड गलती से राइटेबल सीमा की गणना केवल एक बार आरंभ में करता है, tcfp_off_max_hint (अधिकतम स्थिर ऑफ़सेट) का उपयोग करके। यह संकेत किसी भी रनटाइम हेडर ऑफ़सेट को शामिल नहीं करता जो पैकेट संसाधित होने पर टाइप की गई कुंजियाँ जोड़ती हैं। TCP या UDP जैसी कुंजियाँ रनटाइम पर IP हेडर की स्थिति के आधार पर ऑफ़सेट की गणना कर सकती हैं (उदाहरण के लिए, यदि कोई पिछली कुंजी नेटवर्क हेडर को स्थानांतरित करती है)। इस प्रकार, प्रति-कुंजी लूप के दौरान, किसी कुंजी का वास्तविक ऑफ़सेट उस सीमा से अधिक हो सकता है जिसे राइटेबल के रूप में पूर्व-आवंटित किया गया था। फिर कोड skb_store_bits() के माध्यम से पैकेट मेमोरी में लिखता है, लेकिन चूँकि पूर्व-COW’d क्षेत्र से परे का पृष्ठ निजी नहीं बनाया गया था, यह लेखन एक ऐसे पृष्ठ को दूषित कर देता है जो अभी भी पेज कैश के साथ साझा है। संक्षेप में, “राइटेबल पैकेट सीमा की गणना बहुत जल्दी करना” एक आउट-ऑफ-बाउंड, क्रॉस-पेज लेखन का कारण बनता है। नकारात्मक ऑफ़सेट (जैसे इनग्रेस पर Ethernet हेडर संपादित करना) भी गलत तरीके से संभाले जाते हैं, और यहाँ तक कि offset_valid() में भी INT_MIN के लिए सुरक्षा का अभाव था, जिससे दोष और बढ़ गया।
ऐसा क्यों होता है: यह बग मूल रूप से कॉपी-ऑन-राइट सीमा गणना में एक तार्किक त्रुटि है। कर्नेल ने मान लिया कि स्थिर अधिकतम ऑफ़सेट (लोड समय पर ज्ञात) सभी संपादनों के लिए पर्याप्त था। जब गतिशील ऑफ़सेट वाली कुंजियाँ वास्तव में लागू की गईं, तो वह COW सीमा को अद्यतन करने में विफल रहा। कतारबद्ध संपादनों की एक श्रृंखला के बाद, अंतिम लेखन पूर्व-जाँच क्षेत्र के बाहर स्थित हो सकता है। चूँकि पैकेट बफ़र मेमोरी-मैप्ड फ़ाइल पृष्ठों को संदर्भित कर सकते हैं (उदाहरण के लिए ज़ीरो-कॉपी तंत्र के माध्यम से), यह “आंशिक COW” लेखन डिस्क पर किसी फ़ाइल के पेज कैश तक पहुँच सकता है। व्यवहार में, पैकेट संपादक क्रिया को sendfile या splice से पृष्ठ प्राप्त हो सकते हैं; इस प्रकार एक एकल पैकेट फ़िल्टर ऑपरेशन अप्रत्यक्ष रूप से हमलावर-चयनित डेटा को फ़ाइल की इन-मेमोरी छवि में लिख सकता है, बिना डिस्क को बदले।
घटक और डेटा प्रवाह: संवेदनशील कोड Linux net/sched सबसिस्टम (act_pedit.c) में स्थित है। जब कोई पैकेट कॉन्फ़िगर किए गए pedit नियम से मेल खाता है, तो tcf_pedit_act() आह्वान किया जाता है। आंतरिक रूप से यह skb_ensure_writable(skb, X) को ठीक एक बार कॉल करता है, जहाँ X = tcfp_off_max_hint है। यह पैकेट के पहले X बाइट्स को निजी (COW’d) बनाता है। फिर, प्रत्येक कुंजी (संपादन ऑपरेशन) पर एक लूप में, यह कुंजी के वास्तविक लेखन ऑफ़सेट की गणना रनटाइम हेडर ऑफ़सेट को कुंजी के निर्दिष्ट ऑफ़सेट में जोड़कर करता है, और पैकेट में एक 32-बिट मान लिखता है। स्यूडोकोड में:```c
u32 off_max = action->tcfp_off_max_hint;
skb_ensure_writable(skb, off_max);
for (i = 0; i < num_keys; i++) {
u32 hdr_off = compute_header_offset(skb, key[i].hdr_type);
u32 write_off = hdr_off + key[i].offset;
skb_store_bits(skb, write_off, &key[i].value, 4);
}
क्योंकि `hdr_off` की गणना केवल प्रत्येक key को संसाधित करते समय की जाती है, प्रारंभिक `skb_ensure_writable()` कॉल इसके लिए जिम्मेदार नहीं थी। यदि `hdr_off + key[i].offset` `off_max` से अधिक हो जाता है, तो कोड मुख्य रैखिक क्षेत्र के बजाय fragments पर `skb_store_bits()` पर वापस आ जाता है, जिसका अर्थ है कि यह एक ऐसे पृष्ठ में लिखता है जिसे private नहीं बनाया गया था। यही विफलता बिंदु है।
**आक्रमण सतह:** केवल आवश्यक इंटरफ़ेस **tc filter** है जिसमें `pedit` क्रिया होती है, जिसके लिए सामान्यतः **CAP_NET_ADMIN** क्षमता की आवश्यकता होती है। हालाँकि, सामान्य उपयोगकर्ता एक निजी नेटवर्क नेमस्पेस (user namespace cloning) के भीतर वास्तविक विशेषाधिकारों के बिना CAP_NET_ADMIN प्राप्त कर सकते हैं। इस प्रकार, एक अनविशेषाधिकार प्राप्त उपयोगकर्ता user+net नेमस्पेस में प्रवेश कर सकता है और loopback पर `tc pedit` नियम बना सकता है। लेखन तब होता है जब एक पैकेट संसाधित होता है (हमलावर आमतौर पर इसे ट्रिगर करने के लिए loopback पर ट्रैफ़िक उत्पन्न करता है)। विश्वास सीमा (user बनाम kernel) पार हो जाती है क्योंकि kernel ने अपने स्वयं के COW सेटअप पर भरोसा किया, लेकिन उपयोगकर्ता द्वारा प्रदान किए गए ऑफ़सेट ने उस धारणा को तोड़ दिया।