
BPF LSM ब्लॉकर CVE-2026-31431 (Copy Fail) के लिए - OpenShift 4 के लिए शून्य-रीबूट उपचार
CVE-2026-31431 ("Copy Fail") Linux कर्नेल में algif_aead क्रिप्टोग्राफिक इंटरफ़ेस में एक विशेषाधिकार वृद्धि भेद्यता है। एक हमलावर authencesn एल्गोरिथम और splice() के साथ AF_ALG सॉकेट का उपयोग करके कर्नेल पेज कैश में मनमानी फ़ाइलों को दूषित करता है — जिसमें /usr/bin/su जैसे setuid बाइनरी शामिल हैं।
यह दस्तावेज़ BPF LSM DaemonSet का उपयोग करके शून्य-रीबूट उपचार प्रदान करता है जो सभी AF_ALG AEAD बाइंड्स को ब्लॉक करता है — Copy Fail द्वारा शोषित सबसिस्टम। यह क्रिप्टो टेम्पलेट नेस्टिंग (जैसे pcrypt(authencesn(...))) के माध्यम से बायपास को रोकता है। अन्य AF_ALG उपयोग (hash, skcipher) प्रभावित नहीं होते हैं। तीन अलग-अलग OCP 4.22 क्लस्टरों पर एंड-टू-एंड परीक्षण किया गया।
# 1. सत्यापित करें कि BPF LSM सक्षम है (RHEL CoreOS 9.8 में यह डिफ़ॉल्ट रूप से होता है)
oc debug node/<any-node> -- chroot /host cat /sys/kernel/security/lsm
# इसमें "bpf" होना चाहिए
# 2. नेमस्पेस तैनात करें और विशेषाधिकार प्राप्त SCC प्रदान करें
oc apply -f daemonset.yaml
# 3. DaemonSet पॉड्स सभी नोड्स पर स्वचालित रूप से प्रारंभ होंगे
# 4. सत्यापित करें
oc get pods -n block-copyfail # सभी नोड्स Running दिखाने चाहिए
oc logs -n block-copyfail -l app=block-copyfail
# अपेक्षित: "block-copyfail: blocker active — all AF_ALG AEAD binds blocked"
कोई रीबूट नहीं। कोई नोड ड्रेन नहीं। कोई पॉड रीस्टार्ट नहीं। सुरक्षा तत्काल है और सभी नोड्स पर सभी प्रक्रियाओं को कवर करती है (100% कवरेज)।
एक्सप्लॉइट तीन कर्नेल सुविधाओं को जोड़ता है:
socket(AF_ALG, SOCK_SEQPACKET, 0) के माध्यम से कर्नेल क्रिप्टो के लिए यूज़रस्पेस हैंडल बनाता हैauthencesn(hmac(sha256),cbc(aes)) से बाइंड होता है, एक विशिष्ट प्रमाणित एन्क्रिप्शन एल्गोरिथमहमलावर पेज कैश में /usr/bin/su को दूषित करता है (फ़ाइल तक लिखने की पहुंच के बिना), फिर रूट प्राप्त करने के लिए इसे निष्पादित करता है।
अपने क्लस्टर पर एक नया cve-2026-31431-test नेमस्पेस बनाएं और test निर्देशिका में मैनिफेस्ट लागू करके परीक्षण स्क्रिप्ट चलाएं:
oc apply -f test
परिणाम जांचें:
oc wait pod/cve-test -n cve-2026-31431-test \
--for=jsonpath='{.status.phase}'=Succeeded --timeout=120s
oc -n cve-2026-31431-test logs -l app=cve-2026-31431-test
भेद्य क्लस्टर पर आप देखेंगे:
=== CVE-2026-31431 Vulnerability Test ===
Target: /usr/bin/su
Original SHA256: 8969560ae8e6e21c6184c1451f59418822ee69dd5d946d71987b55236bbc0feb
Attempting splice + AF_ALG page-cache corruption (160 bytes in 40 chunks)...
After SHA256: 30b0f5b5a054c4df65b48ca792863bf7054b4d793f15f57163792ba6c2b151ae
PAGE CACHE CORRUPTION: YES - /usr/bin/su was modified in the page cache
Attempting to execute corrupted /usr/bin/su ...
exit code: 0
RESULT: PARTIALLY MITIGATED
Page-cache corruption succeeded (kernel is vulnerable)
Privilege escalation blocked (allowPrivilegeEscalation=false)
oc delete namespace cve-2026-31431-test
BPF LSM दृष्टिकोण कर्नेल स्तर पर socket_bind को हुक करता है और टेम्पलेट नेस्टिंग की परवाह किए बिना सभी AF_ALG AEAD बाइंड्स को ब्लॉक करता है। यह block-copyfail पर आधारित है, जिसे OCP तैनाती के लिए libbpf के साथ C में फिर से लिखा गया है।
BPF LSM सक्षम होना चाहिए। RHEL CoreOS 9.8 (OCP 4.22) में यह डिफ़ॉल्ट रूप से सक्षम है। इससे सत्यापित करें:
oc debug node/<any-node> -- chroot /host cat /sys/kernel/security/lsm
अपेक्षित आउटपुट में bpf शामिल है:
lockdown,capability,landlock,yama,selinux,bpf
यदि bpf मौजूद नहीं है, तो एक बार का MachineConfig आवश्यक है (यह एकमात्र परिदृश्य है जिसमें रीबूट की आवश्यकता होती है):
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
labels:
machineconfiguration.openshift.io/role: worker
name: 99-enable-bpf-lsm
spec:
kernelArguments:
- lsm=lockdown,capability,selinux,bpf
daemonset.yaml मैनिफेस्ट लागू करके एक नया block-copyfail नेमस्पेस बनाएं, SCC प्रदान करें, और DaemonSet तैनात करें।
DaemonSet पॉड्स बनने से पहले विशेषाधिकार प्राप्त SCC प्रदान किया जाना चाहिए, अन्यथा पॉड निर्माण SCC सत्यापन त्रुटियों के साथ विफल हो जाएगा।
oc apply -f daemonset.yaml
oc get pods -n block-copyfail -o wide
अपेक्षित: प्रति नोड एक पॉड, सभी Running:
NAME READY STATUS AGE NODE
block-copyfail-2jhzf 1/1 Running 34s ci-...-master-2
block-copyfail-4dfq7 1/1 Running 34s ci-...-master-1
block-copyfail-c2ts8 1/1 Running 34s ci-...-worker-c
block-copyfail-ctblk 1/1 Running 34s ci-...-worker-a
block-copyfail-m26sx 1/1 Running 34s ci-...-worker-b
block-copyfail-xsh6d 1/1 Running 34s ci-...-master-0
oc logs -n block-copyfail -l app=block-copyfail
अपेक्षित:
block-copyfail: blocker active — all AF_ALG AEAD binds blocked
भेद्यता की पुष्टि अनुभाग से वही एक्सप्लॉइट परीक्षण फिर से चलाएं।
BPF LSM DaemonSet तैनात करने के बाद, आउटपुट होगा:
=== CVE-2026-31431 Vulnerability Test ===
Target: /usr/bin/su
Original SHA256: 30b0f5b5a054c4df65b48ca792863bf7054b4d793f15f57163792ba6c2b151ae
Attempting splice + AF_ALG page-cache corruption (160 bytes in 40 chunks)...
AF_ALG bind failed: [Errno 1] Operation not permitted
RESULT: CANNOT TEST - AF_ALG or splice not available/permitted
DaemonSet लॉग्स अवरुद्ध प्रयास दिखाएंगे:
oc logs -n block-copyfail -l app=block-copyfail
block-copyfail: blocker active — all AF_ALG AEAD binds blocked
block-copyfail: BLOCKED pid=16777 comm=python3 time=2026-05-01 16:37:23
यह पुष्टि करने के लिए कि सभी AEAD एल्गोरिदम ब्लॉक हैं जबकि अन्य AF_ALG प्रकार (hash, skcipher) काम करना जारी रखते हैं, एक नोड पर verify-algos.py चलाएं:
oc debug node/<any-node> -- chroot /host python3 -c "
import socket
tests = [
('aead', 'gcm(aes)'),
('aead', 'ccm(aes)'),
('aead', 'rfc4106(gcm(aes))'),
('hash', 'sha256'),
('skcipher', 'cbc(aes)'),
('aead', 'authencesn(hmac(sha256),cbc(aes))'),
]
for t, n in tests:
s = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
try:
s.bind((t, n))
print(f' ALLOWED {t}/{n}')
except OSError as e:
print(f' BLOCKED {t}/{n} -- {e}')
finally:
s.close()
"
अपेक्षित आउटपुट:
BLOCKED aead/gcm(aes) -- [Errno 1] Operation not permitted
BLOCKED aead/ccm(aes) -- [Errno 1] Operation not permitted
BLOCKED aead/rfc4106(gcm(aes)) -- [Errno 1] Operation not permitted
ALLOWED hash/sha256
ALLOWED skcipher/cbc(aes)
BLOCKED aead/authencesn(hmac(sha256),cbc(aes)) -- [Errno 1] Operation not permitted
यह पुष्टि करता है कि BPF LSM सभी AEAD बाइंड्स को ब्लॉक करता है जबकि अन्य AF_ALG प्रकार कार्यात्मक रहते हैं।
BPF LSM ब्लॉकर स्रोत block-copyfail/ में है:
block-copyfail/
block_copyfail.bpf.c # BPF कर्नेल प्रोग्राम (LSM हुक)
block_copyfail.c # यूज़रस्पेस लोडर (libbpf स्केलेटन)
block_copyfail.h # साझा इवेंट संरचना
Makefile # बिल्ड पाइपलाइन
Dockerfile # मल्टी-स्टेज बिल्ड
daemonset.yaml # नेमस्पेस + DaemonSet मैनिफेस्ट
trigger-test.py # त्वरित सत्यापन स्क्रिप्ट
बिल्ड और पुश:
cd block-copyfail/
podman build -t quay.io/<org>/block-copyfail:latest .
podman push quay.io/<org>/block-copyfail:latest
Dockerfile मल्टी-स्टेज बिल्ड का उपयोग करता है: संकलन के लिए clang/bpftool/libbpf-devel के साथ Fedora, रनटाइम इमेज के लिए UBI 9 minimal (~122 MB)।
DaemonSet को हटाने से सभी नोड्स पर शमन तुरंत हट जाता है:
oc delete -f daemonset.yaml
# या
oc delete namespace block-copyfail
BPF प्रोग्राम लोडर प्रक्रिया से बाहर निकलने पर स्वचालित रूप से डिटैच हो जाता है। कोई रीबूट या पॉड रीस्टार्ट की आवश्यकता नहीं है।