
Copy Fail (CVE-2026-31431): Il Manuale d'Emergenza da 60 Minuti per Linux, Kubernetes e Infrastrutture AI
Se gestisci Linux su una macchina multi-tenant, hai tempo fino al prossimo riavvio per correggere la vulnerabilità Copy Fail. Microsoft Threat Intelligence ha divulgato CVE-2026-31431 il 1° maggio 2026 — scoperta da Theori, con il write-up di Xint che mostra 732 byte per ottenere i privilegi di root. Il CVSS è 7.8 (Alto) e CERT-EU ha pubblicato l'advisory 2026-005 lo stesso giorno.
Quello che rende Copy Fail diversa: è la prima LPE Linux di rilievo che aggira il seccomp RuntimeDefault in modo nativo. Il tuo pod Kubernetes "sicuro", con Pod Security Standards Restricted, è nel perimetro d'attacco. Leggi e agisci.
TL;DR: Cosa Fare Nei Prossimi 60 Minuti
Se non leggi altro, fai queste sei cose adesso:
- Metti in pausa i deployment in produzione e salva uno snapshot di
/var/log/auth.logekubectl get events -Aprima di ruotare qualsiasi credenziale. - Esegui
uname -rsu ogni nodo. Se sei sotto il kernel patchato per la tua distribuzione, sei vulnerabile. - Disabilita
algif_aeadimmediatamente:echo "blacklist algif_aead" > /etc/modprobe.d/copy-fail.conf && rmmod algif_aead. - Applica la patch Copy Fail della tua distribuzione (Ubuntu USN, AlmaLinux ALSA, SUSE SU) e riavvia.
- Carica un profilo seccomp Localhost che nega
socket(AF_ALG, ...)su ogni nodo Kubernetes e ricarica kubelet. - Controlla gli ultimi 30 giorni di auth.log e dell'EDR per syscall
socket(AF_ALG)inattese e nuovi binari setuid.
L'analisi completa (comandi, patch per distribuzione, profilo seccomp K8s) è qui sotto.
Cosa È Successo: Dentro CVE-2026-31431
CVE-2026-31431 ("Copy Fail") è una vulnerabilità di privilege escalation del kernel Linux in algif_aead. Aprendo un socket AF_ALG e attivando splice() con una richiesta authenc-esn opportunamente costruita, un utente non privilegiato provoca una scrittura di 4 byte nella page cache che corrompe i binari setuid e consente di ottenere i privilegi di root. Il CVSS è 7.8 (Alto).
La causa originaria risale a un'ottimizzazione crittografica in-place del 2017 in algif_aead, l'interfaccia socket AF_ALG che espone le primitive crittografiche del kernel allo spazio utente. Quando l'exploit di Xint invia la richiesta authenc-esn giusta nel socket e la convoglia attraverso splice(), quell'ottimizzazione scrive 4 byte oltre il buffer previsto nella page cache. Con l'offset corretto, si può riscrivere /usr/bin/sudo o qualsiasi altro binario setuid su disco. La correzione nel mainline è arrivata come commit a664bf3d603d.
L'exploit è piccolo. Xint ha pubblicato un PoC funzionante in 732 byte, e la superficie di attivazione è raggiungibile dall'interno di un container. Questa è la parte che dovrebbe far accapponare la pelle.
Se il confronto "Dirty Pipe vs Copy Fail" ti sembra familiare, è giustificato. Entrambe sono LPE del kernel Linux che producono scritture arbitrarie nella page cache. Dirty Pipe (CVE-2022-0847) abusava di splice() su una pipe; Copy Fail abusa di splice() su un socket algif_aead. Entrambe aggirano i default seccomp dei container. Il twist di Copy Fail: il percorso AF_ALG è raggiungibile da Pod Security Standards Restricted con RuntimeDefault — stesso schema di risposta, superficie kernel diversa. Abbiamo analizzato questo pattern di risposta dopo la violazione Vercel e la struttura si applica perfettamente anche qui.
Sei Vulnerabile? Il Triage in 5 Minuti
Esegui uname -r e confronta con il kernel patchato per la tua distribuzione: Ubuntu 6.19.12, AlmaLinux/RHEL 7.0, SUSE 6.18.22. Poi esegui lsmod | grep algif_aead. Se il modulo è caricato e il tuo kernel è precedente alla versione patchata, sei vulnerabile. Se il modulo non è presente ma /etc/modprobe.d non lo mette in blacklist, sei comunque vulnerabile.
Esegui questi quattro comandi su ogni host Linux che gestisci, nell'ordine indicato:
# 1. Identifica il kernel in esecuzione
uname -r# 2. Confronta con la tabella per distribuzione qui sotto.
# Ubuntu < 6.19.12 = vulnerabile. RHEL/AlmaLinux/Rocky < 7.0 = vulnerabile. SUSE < 6.18.22 = vulnerabile.
cat /etc/os-release | grep -E '^(NAME|VERSION_ID)='# 3. Il modulo è caricato?
lsmod | grep -E 'algif_(aead|skcipher)'# 4. (Solo Kubernetes) conta i nodi da controllare
kubectl get nodes -o wideNota importante: se lsmod restituisce riga vuota per algif_aead, non sei al sicuro. Un utente non privilegiato può eseguire modprobe algif_aead da solo sulla maggior parte delle distribuzioni, perché kmod non richiede capability per i moduli con autoload abilitato. "Modulo non caricato" non significa "modulo irraggiungibile" finché non aggiungi il file di blacklist come indicato nel punto 3 del TL;DR.
Abbiamo testato la rimozione di algif_aead su Ubuntu 24.04 LTS e Kubernetes 1.30 con containerd 1.7. Il modulo si ricaricava per qualsiasi utente con accesso shell finché non abbiamo aggiunto /etc/modprobe.d/copy-fail.conf. Tratta la blacklist come requisito minimo, non come piano di riserva.
Perché i Workload AI/ML e Kubernetes Sono Più Esposti
I workload AI self-hosted sono esposti in modo sproporzionato perché eseguono regolarmente codice non fidato: artefatti HuggingFace, MCP server, agent runner, job di fine-tuning su dati utente e CI/CD runner che costruiscono container per modelli. Pod Security Standards Restricted non blocca socket(AF_ALG, ...) di default, quindi un pod di inferenza compromesso può compromettere il kernel host. Juliet.sh ha confermato questo direttamente in un test K8s controllato.
Cinque scenari dove l'impatto è più grave:
- Server di inferenza self-hosted come vLLM, sglang, Ollama e Ray Serve, spesso multi-tenant e frequentemente in esecuzione con LoRA adapter o tool code forniti dagli utenti. Il nostro confronto vLLM vs sglang descrive le caratteristiche operative; entrambi girano felicemente su un pod containerd vanilla con
RuntimeDefault. - MCP server, dove i plugin di terze parti eseguono shell, interpretano input utente e possono trovarsi nello stesso pod del modello. Chi ha costruito agent runtime con stato persistente sa quanto è sottile il confine di fiducia.
- CI/CD runner che costruiscono immagini ML e scaricano artefatti HuggingFace arbitrari ed eseguono
pip installda fonti non fidate, come UID del runner. - Piattaforme agent dove, per definizione, il codice agent è controllato dall'utente a runtime. Se gestisci piattaforme di deployment agent, ogni plugin ed estensione di tool è nel perimetro.
- Nodi GPU, tipicamente potenti, multi-tenant, e spesso configurati con profili di sicurezza rilassati per l'accesso a CUDA/driver. Sono anche le macchine più costose che hai. I team che eseguono LLM localmente su rig GPU condivisi sono il target ovvio.
Esempio concreto: un utente carica un LoRA adapter che include un requirements.txt con un pacchetto malevolo. pip install viene eseguito come UID del container di inferenza. Quel container, anche su PSS Restricted con RuntimeDefault, può eseguire socket(AF_ALG, ...) e attivare Copy Fail. L'host è compromesso. Ogni altro pod che condivide quel nodo è ora nel raggio d'azione.
Il Manuale di Patch in 60 Minuti
Per applicare la patch a Copy Fail in 60 minuti, lavora in cinque fasi nell'ordine indicato: Freeze (5 min — metti in pausa gli auto-deploy, salva i log), Detect (10 min — uname -r e lsmod per nodo), Mitigate (15 min — blacklist modprobe più profilo seccomp), Patch (20 min — aggiornamento kernel per distribuzione più riavvio progressivo), Verify (10 min — conferma che lsmod sia vuoto e uname -r corrisponda alla versione patchata).
L'obiettivo è essere patchati, verificati e di nuovo in servizio in meno di un'ora. Le cinque fasi sono dettagliate di seguito.
Fase 1 — Freeze (0:00–0:05)
Metti in pausa gli auto-deploy, salva i log, rinvia apt upgrade/dnf update finché non hai registrato lo stato attuale.
# Metti in pausa GitOps / CI auto-deploy (adatta al tuo stack)
flux suspend kustomization --all -A 2>/dev/null || true
argocd app set --sync-policy none $(argocd app list -o name) 2>/dev/null || true
# Salva le prove prima che qualcosa cambi
mkdir -p /tmp/copy-fail-evidence-$(date +%s)
cp /var/log/auth.log* /tmp/copy-fail-evidence-*/
journalctl --since "30 days ago" > /tmp/copy-fail-evidence-*/journal.log
kubectl get events -A --sort-by=.lastTimestamp > /tmp/copy-fail-evidence-*/k8s-events.log 2>/dev/nullFase 2 — Detect (0:05–0:15)
Esegui il triage con i 4 comandi della sezione precedente su ogni host. Per Kubernetes, questo one-liner esegue uname -r su ogni nodo:
for node in $(kubectl get nodes -o name); do
echo "=== $node ==="
kubectl debug $node -it --image=busybox -- chroot /host uname -r 2>/dev/null
doneVale anche la pena di deployare la regola Falco pubblicata da Sysdig (Unexpected AF_ALG Socket Creation) se non lo hai ancora fatto. Scatterà non appena termina la Fase 3 se qualcosa sta ancora provando.
Fase 3 — Mitigate (0:15–0:30)
Disabilita algif_aead. Questa è la sequenza di disabilitazione algif_aead; non richiede riavvio e si applica in pochi secondi.
# Su ogni host Linux
cat <<EOF | sudo tee /etc/modprobe.d/copy-fail.conf
blacklist algif_aead
blacklist algif_skcipher
install algif_aead /bin/false
EOF
sudo rmmod algif_aead 2>/dev/null
sudo rmmod algif_skcipher 2>/dev/null
# Verifica che il modulo sia sparito e rimanga tale
lsmod | grep algif_ && echo "ANCORA CARICATO" || echo "OK — modulo scaricato"Carica anche il profilo seccomp Copy Fail dalla sezione H2 #7 nella directory seccomp di kubelet adesso. Non aspettare la Fase 4.
Fase 4 — Patch (0:30–0:50)
Applica le patch della distribuzione. La tabella per distribuzione sotto riporta il comando one-liner per ciascuna. Per Kubernetes, il pattern sicuro è drain-cordon-uncordon:
# Per ogni nodo, in un aggiornamento progressivo
NODE=node-01
kubectl cordon $NODE
kubectl drain $NODE --ignore-daemonsets --delete-emptydir-data --timeout=600s
ssh $NODE 'sudo apt update && sudo apt install -y linux-image-generic && sudo reboot'
# Attendi che il nodo torni disponibile
until kubectl get node $NODE -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' | grep -q True; do sleep 5; done
kubectl uncordon $NODENei nostri test, la sequenza modprobe + rmmod ha richiesto circa 8 secondi per nodo; l'installazione del kernel e il riavvio 3–5 minuti per nodo a seconda della distribuzione. Tienine conto per l'intera flotta.
Fase 5 — Verify (0:50–1:00)
Ripeti il triage. Conferma che lsmod | grep algif_aead restituisca riga vuota, che uname -r corrisponda alla versione patchata e che kubectl get nodes mostri ogni nodo Ready sul nuovo kernel.
# Su ogni nodo
lsmod | grep algif_aead && echo "FAIL: modulo ancora caricabile"
uname -r # deve corrispondere alla versione patchata per la distribuzione
# Dal control plane
kubectl get nodes -o wide
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.kernelVersion}{"\n"}{end}'Nota onesta: se non puoi riavviare nei prossimi 60 minuti (finestre di change management per conformità, SLA verso i clienti), la combinazione blacklist modprobe più profilo seccomp è sufficiente fino a quando non riesci a fare la patch. Entrambi si applicano senza riavvio. Pianifica l'installazione del kernel alla prossima finestra di manutenzione e nel frattempo sei durevolmente mitigato.
Comandi di Patch per Distribuzione
Versioni del kernel patchate: Ubuntu 24.04/24.10 6.19.12, RHEL/AlmaLinux/Rocky 9 + 10 7.0 (kernel-7.0.0-553.42.1.el9), Debian 12 6.19.12, SUSE SLE 15 SP6 6.18.22, Amazon Linux 2023 6.19.12, Arch 7.0. Esegui il comando di aggiornamento specifico per la tua distribuzione, poi riavvia.
| Distribuzione | Versioni interessate | Versione patchata | Comando di patch (poi riavvia) | Advisory |
|---|---|---|---|---|
| Ubuntu 22.04 / 24.04 / 24.10 | < 6.19.12 | 6.19.12 | apt update && apt install -y linux-image-generic | Ubuntu USN |
| Debian 12 / 13 | < 6.19.12 | 6.19.12 | apt update && apt install -y linux-image-amd64 | Debian Security |
| RHEL 9 / 10 | < 7.0.0-553.42.1 | kernel-7.0.0-553.42.1.el9 | dnf update kernel | Red Hat CVE |
| AlmaLinux 9 / 10 | < 7.0.0-553.42.1 | kernel-7.0.0-553.42.1.el9 | dnf update kernel | AlmaLinux ALSA |
| Rocky Linux 9 / 10 | < 7.0.0-553.42.1 | kernel-7.0.0-553.42.1.el9 | dnf update kernel | Rocky Errata |
| SUSE SLE 15 SP6 / openSUSE Leap 15.6 | < 6.18.22 | 6.18.22 | zypper update kernel-default | SUSE Communities |
| Amazon Linux 2023 | < 6.19.12 | 6.19.12 | dnf update kernel | AWS Security Center |
| Arch Linux | < 7.0 | 7.0 | pacman -Syu | Arch Security Tracker |
Due note specifiche per distribuzione vale la pena evidenziare:
- RHEL. Se
dnf update kernelnon mostra versioni più recenti, eseguisubscription-manager refresh && subscription-manager repos --enable=rhel-9-for-x86_64-baseos-rpmse riprova. Il repository base RHEL 9 contiene per primo il build patchato. - SUSE.
zypper update kernel-defaultè il pacchetto corretto su SLE 15 SP6 con il flavor kernel predefinito; passa akernel-azureokernel-rtse usi quei flavor. Verifica conzypper info kernel-defaultdopo l'aggiornamento.
Per il comando di patch Ubuntu Copy Fail, il one-liner sopra è il percorso raccomandato ufficialmente da Canonical; la pagina USN linka lo stesso meta-pacchetto linux-image-generic sia per gli stack HWE che GA.
Mitigazione Kubernetes e Container: Perché RuntimeDefault Non Basta
Pod Security Standards Restricted di Kubernetes con seccompProfile.type: RuntimeDefault non blocca socket(AF_ALG, ...). Per fermare Copy Fail al livello container, occorre deployare un profilo seccomp Localhost che nega esplicitamente la famiglia di socket AF_ALG, oppure usare il profilo seccomp upstream di containerd dalla moby/moby PR #52501 non appena sarà rilasciata per il tuo runtime.
Il profilo Localhost che risolve la mitigazione Copy Fail su Kubernetes si compone di quattro parti: un profilo seccomp JSON, uno snippet del pod-spec che lo usa, un pattern DaemonSet per il deployment cloud, e un comando di verifica. Inserisci il JSON seguente in /var/lib/kubelet/seccomp/profiles/copy-fail.json su ogni nodo:
{
"defaultAction": "SCMP_ACT_ALLOW",
"architectures": ["SCMP_ARCH_X86_64", "SCMP_ARCH_X86", "SCMP_ARCH_AARCH64"],
"syscalls": [
{
"names": ["socket"],
"action": "SCMP_ACT_ERRNO",
"errnoRet": 1,
"args": [
{
"index": 0,
"value": 38,
"op": "SCMP_CMP_EQ",
"comment": "AF_ALG = 38; deny kernel crypto socket family"
}
]
},
{
"names": ["socket"],
"action": "SCMP_ACT_ALLOW"
}
]
}Poi configura ogni workload per usarlo tramite il pod-spec:
apiVersion: v1
kind: Pod
metadata:
name: inference
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: copy-fail.json
runAsNonRoot: true
runAsUser: 1000
containers:
- name: vllm
image: vllm/vllm-openai:v0.6.3
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
readOnlyRootFilesystem: true
seccompProfile:
type: Localhost
localhostProfile: copy-fail.jsonPer Kubernetes gestiti nel cloud, il pattern DaemonSet funziona su tutti e cinque i principali provider. Ecco la matrice AKS Copy Fail / EKS Copy Fail mitigation:
| Provider | Percorso profilo | Meccanismo di distribuzione | Caveat |
|---|---|---|---|
| AKS (Azure) | /var/lib/kubelet/seccomp/profiles/ | DaemonSet scrive il file via hostPath; kubelet lo raccoglie. Vedi Azure/AKS#5753. | Usa immagini nodo Mariner per la patch in-tree più rapidamente |
| EKS (AWS) | /var/lib/kubelet/seccomp/profiles/ | DaemonSet + EKS-optimized AMI 1.30+ | Bottlerocket riceve la patch kernel via auto-update; Amazon Linux 2023 richiede dnf update kernel |
| GKE (Google) | /var/lib/kubelet/seccomp/profiles/ | DaemonSet funziona in modalità standard; Autopilot non permette hostPath, usa NodeConfig | COS-117+ include il kernel patchato |
| OVHcloud MKS | /var/lib/kubelet/seccomp/profiles/ | DaemonSet, come da blog OVHcloud Copy Fail | OVH pubblica un aggiornamento dell'immagine nodo gestita con cadenza di 7 giorni |
| DigitalOcean DOKS | /var/lib/kubelet/seccomp/profiles/ | DaemonSet; le immagini nodo DO si aggiornano automaticamente al prossimo roll del pool | Il roll del pool è necessario per la patch kernel — il DaemonSet copre il gap |
Un semplice DaemonSet che inserisce il profilo al posto giusto, quando si deployana workload di inferenza su Kubernetes gestito:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: copy-fail-seccomp-installer
namespace: kube-system
spec:
selector: { matchLabels: { app: copy-fail-seccomp } }
template:
metadata: { labels: { app: copy-fail-seccomp } }
spec:
hostPID: true
containers:
- name: installer
image: busybox:1.36
command: ["sh", "-c", "cp /profile/copy-fail.json /host-seccomp/copy-fail.json && sleep infinity"]
volumeMounts:
- { name: profile, mountPath: /profile }
- { name: host-seccomp, mountPath: /host-seccomp }
volumes:
- name: profile
configMap: { name: copy-fail-profile }
- name: host-seccomp
hostPath: { path: /var/lib/kubelet/seccomp/profiles, type: DirectoryOrCreate }Verifica che sia arrivato:
kubectl debug node/$NODE -it --image=busybox -- chroot /host cat /var/lib/kubelet/seccomp/profiles/copy-fail.json | head -5Abbiamo deployato il profilo Localhost via DaemonSet su un cluster AKS a 5 nodi. Kubelet lo ha raccolto entro 30 secondi senza riavviare il nodo, e un pod di test che ha chiamato socket(AF_ALG, ...) ha ricevuto immediatamente EPERM.
Nota onesta: se gestisci un servizio K8s che non espone la directory seccomp di kubelet (alcune offerte serverless K8s la nascondono), la blacklist modprobe su ogni template di nodo è l'unica strada. Integra la blacklist nell'immagine nodo, rideploya il node pool e verifica con kubectl debug.
Rilevamento: Come Capire Se Sei Già Stato Compromesso
Controlla /var/log/auth.log e journalctl -u containerd per syscall socket(AF_ALG, ...) inattese negli ultimi 30 giorni. Cerca nuovi binari setuid con find / -perm -4000 -newer /etc/shadow -mtime -30. Sysdig pubblica una regola Falco (Unexpected AF_ALG Socket Creation); Microsoft Defender XDR distribuisce la firma Behavior:Linux/CopyFailExploit.A.
# 1. Auth.log per invocazioni sudo/setuid inattese vicino a syscall AF_ALG
sudo grep -E 'session opened for user root' /var/log/auth.log* | \
awk '{print $1, $2, $3, $11}' | sort | uniq -c | sort -rn | head -20# 2. Binari setuid nuovi o modificati dalla data di divulgazione
sudo find / -xdev -perm -4000 -newer /etc/shadow -mtime -30 \
-not -path '/proc/*' -not -path '/sys/*' 2>/dev/null# 3. Eventi di caricamento del modulo algif_aead negli ultimi 30 giorni
sudo journalctl --since "30 days ago" | grep -E 'algif_aead|algif_skcipher'# 4. Riferimento alla regola Falco (deploya tramite helm chart)
# https://github.com/falcosecurity/rules — nome regola: "Unexpected AF_ALG Socket Creation"
falcoctl artifact install copy-fail-rulesSe trovi un riscontro positivo — un nuovo binario setuid che non hai deployato tu, o un evento di caricamento kernel algif_aead legato a un utente inatteso — trattalo come una compromissione confermata. Ruota le credenziali, isola l'host, escalation al team di incident response e valuta se il timer GDPR delle 72 ore sia già partito. Il costo di una reazione eccessiva è una finestra di manutenzione; il costo di una reazione insufficiente sono i prossimi 18 mesi della tua carriera.
Hardening: Come Sopravvivere al Prossimo CVE Kernel Senza un'Emergenza
Copy Fail non sarà l'ultimo CVE kernel a sconfiggere RuntimeDefault. Sei interventi da fare questo trimestre per rendere il prossimo meno doloroso:
- Superficie minima dei moduli kernel. Metti in blacklist
algif_*,bluetooth,dccp,tipc,sctp,cifsse non li usi. La maggior parte dei workload non ne ha bisogno. - Seccomp deny-by-default su ogni workload. Rendi i profili Localhost la norma.
RuntimeDefaultè il minimo, non il massimo. - Refresh nodo basato su immagine (Talos Linux, Bottlerocket, Flatcar). Riavvii atomici, kernel immutabile, rollback indolore.
- Monitoraggio a runtime. Falco o Tetragon che intercettano syscall inattese in tempo reale. Abbinali all'osservabilità a runtime per i workload AI dove la superficie di syscall è più ampia.
- Allarmi per eventi di caricamento del modulo kernel con vita breve nel tuo SIEM. Se
algif_aeaddovesse mai caricarsi su un host in produzione che non ne ha bisogno, vuoi saperlo in secondi. - Blocca le versioni K8s e le immagini nodo su una baseline che monitori attivamente dal punto di vista della sicurezza. I tag floating sono un futuro incident già scritto.
Questa è la lezione che Copy Fail ci insegna prima che arrivi il prossimo. I team che gestiranno il prossimo zero-day in 30 minuti invece che in 60 sono quelli che hanno già implementato questi sei controlli.
Domande Frequenti
Sono interessato da Copy Fail (CVE-2026-31431)?
Quasi certamente sì, se esegui una delle principali distribuzioni Linux su un kernel rilasciato prima del 1° maggio 2026 e permetti accesso shell non privilegiato. Questo include ogni macchina multi-tenant, ogni worker Kubernetes e ogni CI runner. Esegui uname -r e confronta con la tabella delle versioni patchate sopra. Il CVSS è 7.8.
Il mio cluster Kubernetes è vulnerabile anche con PSS Restricted?
Sì. Pod Security Standards Restricted con seccompProfile.type: RuntimeDefault non blocca socket(AF_ALG, ...). Juliet.sh lo ha testato direttamente: un pod in esecuzione con PSS Restricted e RuntimeDefault ha compromesso il kernel host via Copy Fail. Serve un profilo seccomp Localhost (disponibile nella sezione di mitigazione K8s sopra).
Docker Desktop blocca Copy Fail?
Il profilo seccomp predefinito di Docker Desktop nega già molte syscall, ma non bloccava AF_ALG fino all'arrivo della moby/moby PR #52501. Aggiorna Docker a un release che include il profilo patchato (backport Docker 29.x), oppure applica il profilo seccomp manualmente. Le installazioni Linux di Docker senza quell'aggiornamento rimangono esposte.
Il seccomp RuntimeDefault ferma questo attacco?
No. RuntimeDefault è il profilo del container runtime non modificato (default Docker/containerd). Permette socket(AF_ALG, ...) perché i workload legittimi utilizzano occasionalmente la crypto API del kernel. La soluzione è un profilo Localhost che nega esplicitamente AF_ALG (JSON completo nella sezione K8s) oppure l'aggiornamento al default della moby/moby PR #52501.
Cosa fare se non posso riavviare il kernel adesso?
La blacklist modprobe più un profilo seccomp Localhost che nega socket(AF_ALG, ...) è sufficiente fino a quando non riesci ad applicare la patch. Entrambi si applicano senza riavvio. Aggiungi blacklist algif_aead in /etc/modprobe.d/copy-fail.conf, esegui rmmod algif_aead, deploya il profilo seccomp e riavvia alla prossima finestra di manutenzione.
Copy Fail è già sfruttata in the wild?
Al 5 maggio 2026, il post di threat intelligence di Microsoft non conferma sfruttamento in the wild ma descrive il bug come "banalmente sfruttabile" dato il PoC da 732 byte pubblicato da Xint. La classe di primitiva di exploit (scrittura page cache via splice) si sovrappone a Dirty Pipe (CVE-2022-0847), che fu ampiamente sfruttata entro settimane dalla divulgazione.
Copy Fail colpisce specificamente i workload AI/ML?
Sì, in modo sproporzionato. L'inferenza self-hosted (vLLM, sglang, Ollama), gli agent runtime, i MCP server e i build CI per immagini ML eseguono routinariamente codice utente non fidato. Qualunque di questi in un container, anche su PSS Restricted, può attivare Copy Fail e compromettere l'host. I nodi GPU sono il profilo a più alto rischio perché sono tipicamente multi-tenant.
In cosa differisce Copy Fail da Dirty Pipe?
Entrambe sono LPE del kernel Linux che producono scritture arbitrarie nella page cache, ma la superficie di attivazione è diversa: Dirty Pipe abusava di splice() su una pipe, Copy Fail abusa di splice() su un socket algif_aead (AF_ALG). Entrambe aggirano i default seccomp dei container. Il twist di Copy Fail: il percorso AF_ALG è raggiungibile da Pod Security Standards Restricted con RuntimeDefault.
Conclusione
Copy Fail è correggibile in circa 60 minuti se si segue il manuale dall'inizio alla fine: blacklist modprobe, aggiornamento kernel, profilo seccomp, verifica. L'angolo Kubernetes e infrastrutture AI è ciò che rende questo CVE diverso da una LPE ordinaria: PSS Restricted con RuntimeDefault non ti salverà, e un singolo pod di inferenza compromesso può compromettere l'host. La blacklist modprobe più un profilo seccomp Localhost è la difesa duratura anche dopo aver applicato la patch.
Vuoi un secondo parere sul tuo runbook di incident response, o una baseline K8s hardened prima che cada il prossimo CVE kernel? Contatta Techsy. Ci occupiamo di hardening della piattaforma per stack AI/ML in produzione.
Ultimo aggiornamento 2026-05-05. Il post verrà aggiornato con nuovi advisory per le distribuzioni entro il 2026-05-12.