NVMe-oF/TCP driver vulnerability (CVE-2023-5178)¶
Linux
nvmet-tcptarget'ında bozuk bir Initialize Connection Request işlenirken ortaya çıkan bir logic error, free edilmiş bir pointer'ı erişilebilir bırakır vekmalloc-96içinde racy bir double-free / use-after-free üretir.
Mechanism¶
Başarısız bir queue setup neden double-free üretir
nvmet-tcp, TCP transport için kernel tarafındaki NVMe-over-Fabrics
target'ıdır (drivers/nvme/target/tcp.c). Uzaktaki bir initiator bağlandığında
target socket'i accept eder ve nvmet_tcp_alloc_queue() setup path'ini çalıştırır;
bu path queue başına state ayırır ve (in-band crypto/digest'ler negotiate
edildiğinde) crypto context'i allocate eder. nvmet_tcp_free_crypto() cleanup
helper'ı bu crypto context'i tear down eder.
Bug, NVMe/TCP handshake'inin ilk PDU'su olan bozuk bir Initialize
Connection Request (ICReq)'in error-handling'indeki bir logic error'dur.
Setup'ın ortasında bir failure olduğunda kod yolu bir struct'ı free eder ama
sahip olduğu pointer / state'i tutarlı bir şekilde temizlemez; böylece aynı
allocation ikinci kez serbest bırakılabilir — bir kez failure path'inde, bir kez
de normal queue-release/teardown path'inde (nvmet_tcp_release_queue_work()).
Connection accept ve queue release farklı work context'lerinden çalıştığı için
ikinci free birincisiyle race eder: bu bir racy double-free'dir ve free
edilen object genel amaçlı kmalloc-96 slab cache'ine düşer. Küçük ve yoğun
trafikli bir kmalloc object'inin double-free'i güçlü bir exploitation primitive'idir
— free edilen slot'u saldırgan kontrollü bir object'le reclaim edip ardından stale
reference üzerinde işlem yaparak bir use-after-free'e yönlendirilebilir. Red Hat
advisory'si etkiyi potansiyel remote code execution (network'ten erişilebilir
target) veya local privilege escalation olarak derecelendirir.
Fix'in geri getirdiği invariant basit: bir error path'inde free edilmiş her pointer temizlenmelidir ki sonraki hiçbir teardown path onu tekrar free edemesin.
Walkthrough¶
Target tarafında nvmet / nvmet-tcp yüklü ve bir TCP port configure edilmiş
olmalıdır (default 0.0.0.0:4420); trigger ise kötü niyetli bir initiator'dan gelir.
- Bir NVMe/TCP target ayağa kaldır. Modülleri yükle ve configfs üzerinden bir subsystem ile bir TCP port configure et ki target bağlantıları accept etsin.
modprobe nvmet
modprobe nvmet-tcp
# configure a subsystem + namespace, then a tcp port at addr 0.0.0.0:4420
-
Bağlan ve bozuk bir Initialize Connection Request gönder. Kötü niyetli bir initiator TCP bağlantısını açar ve bir crypto/digest context zaten allocate edilmişken
nvmet_tcp_alloc_queue()'yu error path'ine sürmek için hazırlanmış bir malformed ICReq PDU'su gönderir. -
İki free'yi race ettir. Error path object'i free eder; queue-release work da onu free eder. İki path örtüşecek şekilde teardown'ı tetiklemek
kmalloc-96'da double-free verir. Public PoC (Alon Zahavi / rockrid3r), race'in SLUB freelist davranışı nedeniyle en güvenilir olarak tek CPU'lu bir target'ta çalıştığını not eder. -
UAF'e çevir (exploitation). Double-free edilmiş slot'u kontrollü bir object'le reclaim etmek için küçük
kmalloc-96allocation'ları spray et, ardından stale reference'ın onun üzerinde işlem yapmasına izin ver — böylece double-free'i code execution veya privilege escalation için bir use-after-free'e dönüştür.
Public PoC'tan reproduction notları
rockrid3r exploit'i Ubuntu 23.10'u (kernel 6.5.0-9-generic) hedefler, target'ın
bir NVMe/TCP port expose etmesini gerektirir ve yalnızca 1-core bir target'ta
güvenilir şekilde çalışır — multi-core, race'i kazanmak için ek freelist control
gerektirir. Bug, Alon Zahavi tarafından raporlanmıştır.
Detection¶
- Malformed ICReq PDU'ları alıp ardından aniden disconnect olan bir NVMe/TCP
target bir trigger imzasıdır;
nvmet-tcpiçindeki beklenmedik handshake parse hatalarını logla. kmalloc-96'nın double/use-after-free'i tipik olarakCONFIG_SLUB_DEBUG/ KASAN altındadrivers/nvme/target/tcp.c'den kaynaklanandouble-free or invalid-freeveuse-after-freesplat'ları olarak yüzeye çıkar.
Mitigation¶
- Upstream fix'i uygula (v6.6-rc7'ye merge edildi; Red Hat RHSA-2023:7370 ve SUSE/Ubuntu güncellemeleri gibi distro errata'ları üzerinden backport edildi). Patch, ICReq error path'inde free edilmiş pointer/state'i temizler, böylece teardown onu tekrar free edemez.
- NVMe-oF/TCP target'larını güvenilmeyen network'lere expose etme;
traddr'ı kısıtla /4420port'unu güvenilen initiator'lara firewall'la sınırla.