
एक Ansible role और Python स्क्रिप्ट जो Linux kernel के CVE-2026-98432 के प्रति एक्सपोज़र का पता लगाती है और एक nftables नियम लागू करती है जो IP options ले जाने वाले inbound IPv4 SYN को drop करता है।
Linux kernel के IPv4 TCP कोड में एक use-after-free
(CVE-2026-98432, CVSS 9.8):
आने वाले SYN से सहेजे गए IPv4 options तब मुक्त किए जा सकते हैं जबकि कोई अन्य CPU
अभी भी उन्हें SYNACK बनाने के लिए पढ़ रहा हो, क्योंकि दो destructor पथ उन्हें
RCU grace period की प्रतीक्षा करने के बजाय सादे kfree() से मुक्त कर देते हैं।
अपस्ट्रीम फ़िक्स है
e3f33b0a1d89
("ipv4: free inet_opt and ireq_opt after an RCU grace period")।
2026-10-29 तक किसी भी Ubuntu श्रृंखला के लिए कोई फ़िक्स्ड kernel जारी नहीं हुआ है। Ubuntu के ट्रैकर पर प्रत्येक प्रभावित स्थिति "work in progress" या सीधे vulnerable पढ़ी जाती है, और पृष्ठ कोई शमन सूचीबद्ध नहीं करता। यह पैक ही शमन है।
दोनों रेसिंग पथ ireq->ireq_opt पढ़ते हैं, जो आने वाले SYN से kernel द्वारा सहेजे गए
IPv4 options हैं (tcp_v4_save_options()): SYNACK निर्माण उन्हें पढ़ता है
जबकि child-socket teardown उन्हें मुक्त कर सकता है, और request-socket
migration (net.ipv4.tcp_migrate_req=1, या कोई
BPF_SK_REUSEPORT_SELECT_OR_MIGRATE प्रोग्राम) उन्हीं options को साझा करता है और फिर मुक्त करता है।
जब किसी SYN में कोई IPv4 options नहीं होते, तो ireq_opt NULL होता है: मुक्त करने के लिए
कुछ नहीं और पढ़ने के लिए कुछ नहीं। हमने उस पर निर्भर होने से पहले फ़िक्स कमिट पढ़ा;
दोनों हिस्से उस SYN से शुरू होते हैं जिसमें IPv4 options थे।
इसलिए पैक एक nftables नियम स्थापित करता है जो IP options ले जाने वाले इनबाउंड IPv4 TCP SYNs को ड्रॉप करता है, अपनी अलग टेबल में ताकि यह कभी Docker के, substrate के या वितरण के नियमों से टकराए नहीं:
table inet samp_cve_2026_98432 {
chain prerouting {
type filter hook prerouting priority -300; policy accept;
ip hdrlength > 5 tcp flags & (syn | ack) == syn counter drop \
comment "CVE-2026-98432: drop inbound IPv4 SYN carrying IP options"
}
}
रिलीज़ से पहले एक वास्तविक kernel पर सत्यापित: विकल्पों वाला एक IPv4 SYN काउंटर से टकराता है और गिरा दिया जाता है; एक सादा SYN बिना छुए गुज़र जाता है। TCP ट्रैफ़िक लगभग कभी भी IP विकल्प नहीं ले जाता (कई विकल्प प्रकार कई नेटवर्क्स द्वारा नियमित रूप से गिरा दिए जाते हैं, RFC 7126 के अनुसार), इसलिए नियम की परिचालन लागत लगभग शून्य है।
pve kernel भेजता है,
जिसे Ubuntu का पृष्ठ कवर नहीं करता) unknown रिपोर्ट करते हैं: उनकी
सलाह पढ़ें। नियम स्वयं किसी भी Linux होस्ट की रक्षा करेगा; verdict
तालिकाएँ ही Ubuntu-केवल हैं।नियम kernel मेमोरी में रहता है और डिस्क पर persist नहीं किया जाता। एक
mitigation pack को persistence पथों (units, cron) पर नहीं लिखना चाहिए, और एक
nftables include फ़ाइल केवल वहाँ लोड होती है जहाँ वितरण की nftables
सेवा सक्षम है, जो इन एस्टेट्स पर एकसमान रूप से नहीं है। तो: रीबूट के बाद,
एक डिटेक्शन नियम को अनुपस्थित पढ़ता है (rule_live=0,
हर परिणाम पंक्ति पर persistent=0) और अगला apply इसे पुनर्स्थापित करता है।
रीबूट के बाद apply को दोबारा चलाना ही ऑपरेटिंग मॉडल है, और परिणाम
पंक्ति कभी अन्यथा दावा नहीं करती।
केवल-पढ़ने योग्य, स्वयं को एक निजी अस्थायी निर्देशिका में स्टेज करता है जिसे वह हटा देता है, और रिपोर्ट करता है:
uname -r, इसके पैकेज संस्करण में मैप किया गया)
को प्रति रिलीज़ और flavour Ubuntu के निश्चित संस्करणों के विरुद्ध। बॉक्स की रिलीज़ के लिए कोई फ़िक्स जारी नहीं:
no_fix। एक निश्चित kernel जारी लेकिन चल नहीं रहा: vulnerable, restart_needed=1 के साथ जब यह इंस्टॉल है और
रीबूट की प्रतीक्षा में है (एक इंस्टॉल किया गया फ़िक्स कभी fixed रिपोर्ट नहीं किया जाता)।workaround: true के साथ fixed जब
नियम एक अनिश्चित kernel को कवर करता है; सादा fixed
एक बार चल रहा kernel निश्चित हो जाने पर।not_affected, उन रिलीज़ों और वितरणों के लिए unknown जिन्हें
तालिकाएँ कवर नहीं करतीं।0 स्वच्छ (fixed, not_affected), 2 उजागर या अनिर्णीत (no_fix, vulnerable, unknown: कभी स्वच्छ नहीं), 1 रन
स्वयं विफल, 130 बाधित।syn_options_mitigation/files/samp_common.py samp-common 1.0.4 की बाइट-दर-बाइट प्रति है (dpkg, rpm और apk संस्करण
तुलनाएँ, परिणाम पंक्ति, config लोडिंग)। इसका sha256
samp.yaml में है, और tests/test_samp_pack.py विफल होता है यदि प्रति भिन्न हो। इसे यहाँ कभी
संपादित न करें; samp-common के scripts/vendor.py से इसे पुनः vendor करें।samp/v<version> (यह वाला:
samp/v1.0.1), हार्डवेयर-समर्थित कुंजी से हस्ताक्षरित। substrate
एक हस्ताक्षरित tag आयात करता है, कभी branch नहीं।एक स्क्रिप्ट चरण, एक परिणाम पंक्ति। जब तक चल रहा kernel अनिश्चित है, यह
नियम लोड करता है; एक बार निश्चित kernel चलने पर, यह नियम और
इसकी तालिका हटा देता है। यह उस स्क्रिप्ट, लाइब्रेरी और config के अलावा जिन्हें यह तैनात करता है (जो samp.yaml touches में घोषित हैं) किसी भी फ़ाइल को संपादित नहीं करता, इसलिए परिणाम पंक्ति की backup
सूची खाली है। mitigation को हाथ से हटाना एक कमांड है:
nft delete table inet samp_cve_2026_98432
ansible-playbook -i inventory play.yml # a play that runs the role
python3 syn_options_mitigator.py --config syn_options_config.yaml # detect
sudo python3 syn_options_mitigator.py --config syn_options_config.yaml --apply
जब Ubuntu फ़िक्स्ड कर्नेल जारी करता है, तो ट्रैकर से संस्करणों को रोल डिफ़ॉल्ट्स में syn_options_fixed_versions में पेस्ट करें (कार्य-प्रगति संस्करण पहले से ही एक टिप्पणी में मौजूद हैं) और परिवर्तन को अगले हस्ताक्षरित टैग के रूप में जारी करें; तब डिटेक्शन उनके विरुद्ध vulnerable/restart_needed की रिपोर्टिंग शुरू कर देता है, और apply उन बॉक्स से नियम हटा देता है जो फ़िक्स्ड कर्नेल में रीबूट होते हैं।
python3 -m pytest tests/
यूनिट टेस्ट हर बाहरी कमांड को नकली बनाते हैं; कॉन्ट्रैक्ट टेस्ट
(tests/test_samp_pack.py, samp-common का) रोल के विरुद्ध मैनिफ़ेस्ट की जाँच करता है,
एक स्क्रैच डायरेक्टरी से वास्तविक डिटेक्शन चलाता है और apply
एंट्री को एक-परिणाम-पंक्ति और needrestart नियमों पर बाध्य रखता है।
MIT। देखें LICENSE।
PRs और सुधार स्वागत हैं -> कृपया फ़ोर्क करें और एक मर्ज रिक्वेस्ट सबमिट करें।