AF_ALG crypto socket attack surface¶
AF_ALG(algif) socket ailesi, kernel'in tüm crypto subsystem'ini unprivileged userspace'e açar; bu da karmaşık ve bug açısından zengin, erişilebilir bir attack surface oluşturur.
Mechanism¶
Note
AF_ALG, userspace'in in-kernel crypto API'sini (cipher'lar, hash'ler, AEAD, RNG'ler)
socket'ler üzerinden sürmesine izin verir — aslında dahili tüketiciler (IPsec,
dm-crypt, WireGuard) için tasarlanmış bir işlevsellik. Herhangi bir unprivileged process
bir tane açabilir, hiçbir capability gerekmez; ve seccomp yoksa bir container UID'sinden
bağımsız olarak buna erişebilir. Yapısal kırılganlık — karmaşık reference counting, async
completion callback'leri ve error-path scatter-gather handling — geniş unprivileged
erişilebilirlikle birleşince burayı sürekli tekrar eden bir LPE bug kaynağı yapar.
Walkthrough¶
Bir crypto transform aç ve bind et, sonra üzerinde işlem yap:
int alg = socket(AF_ALG, SOCK_SEQPACKET, 0); /* AF_ALG = 38 */
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "aead",
.salg_name = "gcm(aes)",
};
bind(alg, (struct sockaddr *)&sa, sizeof(sa));
setsockopt(alg, SOL_ALG, ALG_SET_KEY, key, keylen);
int op = accept(alg, NULL, NULL); /* child operation socket */
/* data in/out via sendmsg()/recvmsg() (and splice()) on `op` */
Parent üzerinde accept() çağrısı, her işlem için ayrı bir child socket üretir; algif_aead,
algif_hash, algif_skcipher ise af_alg core'unun üzerinde demand-loaded modüllerdir.
Bu surface üzerinden erişilebilen, doğrulanmış temsili bug'lar:
- CVE-2019-8912 —
af_alg_release_parent()içinde UAF: bir child'ın aktif bir işlemde olup olmadığını kontrol etmeden parent'ın refcount'unu düşüren bir refcount race. - CVE-2021-3543 —
aead_sendmsg()içinde NULL deref: önceki başarısız birrecvmsg()sonrasında gelen birsendmsg(),ctx->tsgl'i NULL bırakıyordu. - CVE-2026-31431 ("Copy Fail") — 2017'den kalma bir in-place optimizasyonu
req->src = req->dstataması yapar ve tag page'lerisg_chain()ile output scatterlist'e zincirler. Userspace socket'isplice()ile beslediğinde, bu tag page'ler spliced dosyanın page cache'ini refere eder; böylece AEAD write cache'lenmiş dosya verisine düşer — file permission'ları bypass eden, arbitrary bir page-cache page'ine 4-byte'lık bir write. PoC:authencesn(hmac(sha256),cbc(aes))'e bind et,/usr/bin/su'nun page cache'ini pipeline'asplice()et, sonra hedef page'e düşen 4-byte'lık bir payload'urecvmsg()et; shellcode'u aşamalı yerleştirmek ve escalate etmek için tekrarla.
Warning
"Copy Fail"'deki page-cache write, kernel page cache'inde kalıcı olur ve eviction'a kadar güvenilen, on-disk bir binary'nin in-memory image'ini tüm kullanıcılar için bozar — güçlü ama gürültülü bir primitive.
Detection¶
Güvenilmeyen context'lerden bir AF_ALG SOCK_SEQPACKET socket oluşturulmasını flag'le;
normal uygulama workload'larında bu nadirdir.
Mitigation¶
socket(AF_ALG, ...)üzerine bir seccomp filter koyarakAF_ALGsocket oluşturmayı blokla.- Userspace crypto socket'lerine ihtiyaç yoksa ilgili config'i (örn.
CONFIG_CRYPTO_USER_API_AEAD) devre dışı bırak. - Kernel'leri patch'li tut: yukarıdaki doğrulanmış bug'lar ilgili stable release'lerinde düzeltilmiştir (örn. "Copy Fail" 7.0 / 6.19.12 / 6.18.22 sürümlerinde fix'lendi).