
حارس eBPF TC ingress مقيّد، وكاشف CO-RE، ومُحمِّل مُتحقَّق منه، ومشرف إطلاق C11 VMM لـ CVE-2026-99999
حارس قبول حزم مؤقت ومُشغِّل خاضع للإشراف لـ CVE-2026-99999.
يقوم بإسقاط حركة المرور الضارة القادمة من الضيف على واجهة TAP الخاصة بالجهاز الافتراضي قبل أن تتمكن نواة المضيف من الوصول إلى skb_checksum_help. مكتوب بلغة C11 الصرفة وeBPF دون أي نصوص برمجية مُفسَّرة.
حالة الأمان: GAL 1 · احتواء CVE غير مُتحقَّق منه · الترقية متوقفة. جميع مجموعات السياسات دون اتصال والكاشفات والمُشغِّل وأدوات التعقيم (sanitizers) تنجح. ومع ذلك، تتحقق مرشحات TC ingress من بايتات حِمل الحزمة، وليس من بيانات virtio الوصفية للتحقق من المجموع الاختباري (
csum_start). يلاحظ كاشف fentry البيانات الوصفية المشبوهة لكنه لا يستطيع حظر التنفيذ.المعالجة الموثوقة: ثبِّت نواة المضيف المُرقَّعة من المورِّد والتي تحتوي على الالتزام upstream
6785011f8b16وأعد التشغيل. يوفِّرcsumguardتقوية حركة مرور الضيف والإشراف وقت التشغيل، وليس تحييد CVE مُتحقَّقًا منه. راجع VALIDATION.md.
flowchart LR
subgraph Guest["Untrusted Guest VM"]
VMM["VMM Process<br/>QEMU or Cloud-Hypervisor"]
end
subgraph Interface["Host TAP Device tap0"]
TAP["tap0 clsact"]
TC["csumguard_in<br/>eBPF TC Ingress"]
end
subgraph Host["Host Linux Kernel"]
STACK["Host Network Stack"]
SINK["skb_checksum_help<br/>Vulnerable Sink"]
end
subgraph Supervisor["csumguard_launch Supervisor"]
MON["Identity Poller<br/>6D Vector State"]
QUAR["Quarantine Engine<br/>SIGSTOP, DOWN, SIGKILL"]
RING["Receipt Ledger<br/>64-slot Ring Buffer"]
end
VMM -->|TX Frames| TAP
TAP --> TC
TC -->|Admitted TCP, UDP, ARP| STACK
TC -.->|Dropped: Frag, GSO, VLAN, Options| DROP["Dropped + Counter"]
STACK -.-> SINK
MON -->|Polls Status| TAP
MON -->|Attachment Drift or Loss| QUAR
QUAR -->|Pauses & Terminates| VMM
QUAR -->|Flushes Receipts| RING
flowchart TD
PKT["Ingress Frame"] --> ETH{"EtherType"}
ETH -->|ARP 0x0806| ARP{"Request or Reply"}
ARP -->|Valid 42B or 60B pad| PASS["PASS: Admitted"]
ARP -->|Invalid| D_ARP["DROP: Malformed ARP"]
ETH -->|IPv4 0x0800| IP{"IPv4 Header Checks"}
ETH -->|Other or VLAN| D_ETH["DROP: Non-IPv4 or VLAN"]
IP -->|Options, Frag, or GSO| D_IP["DROP: Frag, Option, GSO, or Csum"]
IP -->|Valid IHL 5, MF 0, Offset 0| L4{"Transport Protocol"}
L4 -->|TCP proto 6| TCP{"TCP Checks"}
L4 -->|UDP proto 17| UDP{"UDP Checks"}
L4 -->|Other| D_PROTO["DROP: Unsupported Protocol"]
TCP -->|Valid ports and length| PASS
TCP -->|Port 0 or invalid length| D_TCP["DROP: Bad TCP"]
UDP -->|Valid dst port and length| PASS
UDP -->|Port 0 or invalid length| D_UDP["DROP: Bad UDP"]
flowchart TD
S0["1. Preflight<br/>Validate admission.json"] --> S1["2. Attachment<br/>Verify Hash & Attach clsact"]
S1 --> S2["3. Privilege Drop<br/>Non-root UID/GID & no_new_privs"]
S2 --> S3["4. Running<br/>Poll 4-Tuple ID Every 200ms"]
S3 -->|Poll Matches ID| S3
S3 -->|Filter Loss or ID Mismatch| Q0["5. Quarantine: SIGSTOP<br/>Pause VMM Process Group"]
Q0 --> Q1["6. Quarantine: LINK DOWN<br/>Set TAP Interface Down"]
Q1 --> Q2["7. Quarantine: SIGKILL<br/>Terminate Process Group"]
Q2 --> Q3["8. Exit<br/>Flush Hash-Chained Receipts"]
S3 -->|Normal VM Exit| Q3
| المكوّن | الملفات | الدور |
|---|---|---|
| مرشّح الحزم | policy.h، csumguard_tc.bpf.c | مصنّف يعتمد على الترويسة فقط عند مدخل TC. يسمح بـ TCP وUDP وARP القياسية. يُسقط الشُّذَر (fragments) والخيارات (options) وGSO وVLANs. تتعقّب 26 عدّادًا لكل وحدة معالجة مركزية (per-CPU) الأسباب. |
| كاشف المجموع الاختباري | detect_policy.h، csumguard_detect.bpf.c | مسبار fentry اختياري يتعقّب حزم CHECKSUM_PARTIAL داخل النواة. يزيد العدّادات عند الإزاحات المشبوهة. لا يحجب أبدًا. |
| المُحمِّل | loader.c | يتحقّق من صحة مسارات الملفات بدءًا من / لمنع هجمات الروابط الرمزية (symlink). يتحقّق من ملخّصات SHA-256، ويضمن أن الواجهة في حالة DOWN، ويُرفق clsact. |
| مُشغِّل VMM | launch.c، launch_policy.h | يتحقّق من أدلة المشغّل، ويُسقط الامتيازات إلى UID/GID غير جذرية، ويُشغّل VMM، ويراقب الإرفاق. يُوقف الآلة الافتراضية ويقتلها إذا أسقط المرشّح الحزم. |
| سجل الإيصالات | launch.c | خيط غير متزامن يكتب سجلات JSONL متسلسلة تجزئيًا بـ SHA-256 وفق FIPS 180-4. تمنع حلقة المخزن المؤقت ذات 64 خانة تعطّل القرص. |
make EGRESS_MTU=1500 all
make test
ضع الكائن في دليل مملوك للمستخدم الجذر (/opt/csumguard)، وتأكد من أن واجهة TAP في حالة DOWN، ثم أرفق:
/opt/csumguard/csumguard_loader attach tap0 /opt/csumguard/csumguard_tc.bpf.o <EXPECTED_SHA256>
/opt/csumguard/csumguard_loader status tap0 <IFINDEX> <NETNS_INODE> <PROG_ID>
املأ /etc/csumguard/admission.json وابدأ VMM تحت csumguard_launch:
/opt/csumguard/csumguard_launch \
--interface tap0 \
--loader /opt/csumguard/csumguard_loader \
--object /opt/csumguard/csumguard_tc.bpf.o \
--evidence /etc/csumguard/admission.json \
--receipt /var/log/csumguard/tap0.jsonl \
--uid 65534 \
--gid 65534 \
--interval 0.2 \
-- /usr/bin/qemu-system-x86_64 -netdev tap,id=n0,ifname=tap0,script=no,downscript=no
يُحزَّم csumguard ويُوزَّع كـ OCI v1.1 Artifact (application/vnd.csumguard.ebpf.v1) مع مراجع أدلة تشفيرية مرفقة (SLSA v1.0 provenance، وCycloneDX v1.6 SBOM، ومصفوفة التحقق):
# Package local OCI layout and attach all referrers
./oci/package.sh --layout-dir build/oci-layout --tag v0.2.0
# Discover attached referrers graph
oras discover --oci-layout build/oci-layout:v0.2.0
# Pull directly on hypervisor hosts without container daemon
oras pull ghcr.io/mchorfa/csumguard:v0.2.0
راجع oci/README.md للاطلاع على أنواع وسائط OCI الكاملة والواصفات وسير عمل التحقق من Cosign.
# Verify all source and evidence hashes
shasum -a 256 -c SHA256SUMS
# Run offline test suite
make test
# Run AddressSanitizer and UndefinedBehaviorSanitizer
clang -std=c11 -O1 -g -fsanitize=address,undefined -DEGRESS_MTU=1500 -I. tests/test_policy.c -o /tmp/p_asan && /tmp/p_asan
clang -std=c11 -O1 -g -fsanitize=address,undefined -I. tests/test_launch.c -lpthread -o /tmp/l_asan && /tmp/l_asan
clang -std=c11 -O1 -g -fsanitize=address,undefined tests/send_frame.c -o /tmp/f_asan && /tmp/f_asan --self-test