
Garde d'entrée eBPF TC restreinte, détecteur CO-RE, chargeur vérifié et superviseur de lancement VMM en C11 pour CVE-2026-99999
Un garde d'admission de paquets intérimaire et un lanceur supervisé pour CVE-2026-99999.
Il bloque le trafic invité dangereux sur l'interface TAP d'une VM avant que le noyau hôte ne puisse atteindre skb_checksum_help. Écrit en C11 pur et eBPF, sans aucun script interprété.
Statut de sécurité : GAL 1 · Confinement de la CVE non vérifié · Promotion arrêtée. Toutes les suites hors ligne de politique, de détection, de lanceur et de sanitizers passent. Cependant, les filtres TC ingress valident les octets de charge utile des paquets, et non les métadonnées de checksum virtio (
csum_start). Le détecteur fentry observe des métadonnées suspectes mais ne peut pas bloquer l'exécution.Remédiation faisant autorité : Installez le noyau hôte corrigé du fournisseur contenant le commit amont
6785011f8b16et redémarrez.csumguardassure un durcissement du trafic invité et une supervision à l'exécution, et non une neutralisation vérifiée de la CVE. Voir 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
| Composant | Fichiers | Rôle |
|---|---|---|
| Filtre de paquets | policy.h, csumguard_tc.bpf.c | Classificateur header-only à l'ingress TC. Autorise TCP, UDP et ARP standard. Rejette les fragments, options, GSO et VLANs. 26 compteurs par CPU suivent les raisons. |
| Détecteur de checksum | detect_policy.h, csumguard_detect.bpf.c | Sonde fentry optionnelle suivant les paquets CHECKSUM_PARTIAL dans le noyau. Incrémente des compteurs sur des offsets suspects. Ne bloque jamais. |
| Chargeur | loader.c | Valide les chemins de fichiers depuis / pour prévenir les attaques par lien symbolique. Vérifie les empreintes SHA-256, s'assure que l'interface est DOWN et attache clsact. |
| Lanceur de VMM | launch.c, launch_policy.h | Valide les preuves de l'opérateur, abandonne les privilèges vers un UID/GID non-root, démarre le VMM et surveille l'attachement. Met en pause et tue la VM si le filtre se détache. |
| Registre de reçus | launch.c | Thread asynchrone écrivant des enregistrements JSONL chaînés par hachage SHA-256 FIPS 180-4. Un tampon circulaire de 64 emplacements prévient les blocages disque. |
make EGRESS_MTU=1500 all
make test
Placez l'objet dans un répertoire appartenant à root (/opt/csumguard), assurez-vous que l'interface TAP est DOWN, puis attachez :
/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>
Remplissez /etc/csumguard/admission.json et démarrez le VMM sous 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 est empaqueté et distribué sous forme d'Artefact OCI v1.1 (application/vnd.csumguard.ebpf.v1) avec des référents de preuve cryptographique attachés (provenance SLSA v1.0, SBOM CycloneDX v1.6 et matrice de vérification) :
# 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
Voir oci/README.md pour les types de médias OCI complets, les descripteurs et les workflows de vérification Cosign.
# Verify all source and evidence hashes
shasum -a 256 -c SHA256SUMS
# Run offline test suite
make test