nft_object cross-table reference UAF (CVE-2022-2586)¶
Bir nftables object'i veya expression'ı, farklı bir tabloda yaşayan bir set'i reference edebiliyor; o diğer tabloyu silmek set'i free ederken cross-table reference hâlâ ona işaret ediyor ve CAP_NET_ADMIN ile root'a exploit edilebilir bir use-after-free veriyor.
Mechanism¶
References must not cross a lifetime boundary
nf_tables'ta lifetime tablo başına yönetilir: bir tabloyu silmek onun set'lerini, chain'lerini ve object'lerini tek bir transactional birim olarak söker ve free eder. Örtük invariant şudur: A object'inden B set'ine bir reference, yalnızca ikisi de aynı tabloda yaşadığı sürece geçerlidir, çünkü binding/refcount mantığının hesapladığı tek lifetime budur.
nf_tables bir context içinde bir set'i isme göre aramana izin verir ve binding path'i, reference edilen set'in reference eden object/expression ile aynı tabloya ait olmasını zorunlu kılmadı. Yani T1 tablosundaki bir object (veya expression, örneğin bir lookup/dynset) T2 tablosundaki bir set'i bind edebiliyordu. Set'in binding refcount'u T1'in değil, T2'nin lifetime'ı altında izlenir. T2 silindiğinde onun set'i free edilir — ama T1'in object'i artık-free-edilmiş struct nft_set'e hâlâ pointer tutar. O object'in sonraki herhangi bir kullanımı free edilmiş belleği dereference eder: ders kitabı bir UAF. Bu, nf_tables cross-table object reference ile aynı sınıftır; burada özellikle set object'inin tablolar arası lifetime'ı hakkındadır.
Walkthrough¶
netlink (NFNL_SUBSYS_NFTABLES) üzerinden sürülür, herhangi bir user veya network namespace'de CAP_NET_ADMIN gerektirir (unshare -Urn aracılığıyla unprivileged erişilebilir):
NFT_MSG_NEWTABLET2, ardındanNFT_MSG_NEWSETT2 içinde S set'ini oluştur.NFT_MSG_NEWTABLET1, ardından T1'de S'yi isme göre reference eden bir object/expression oluştur (lookup, T2'de yaşamasına rağmen S'yi çözer).NFT_MSG_DELTABLET2 — S, T2'yi sökmenin bir parçası olarak free edilir. T1'in object'i bir danglingnft_set *tutar.- T1'de free edilen set'i dereference eden herhangi bir işlemi tetikle (örneğin expression'ı evaluate etmek ya da T1'i dump/delete etmek) → use-after-free.
-
- ve 4. adımlar arasında, S'nin slab'ını kontrollü bir object ile reclaim et ki dereference attacker-şekilli belleği okusun/yazsın. Uygun reclaim primitive'leri için bkz. elastic objects.
KASAN signature
Fonksiyon adları ve boyutlar kernel'e göre değişir; spesifikleri alıntılamadan önce yeniden üretin.Introduced ~v3.16, very wide exposure
Bug, 958bee14d071 commit'iyle ("netfilter: nf_tables: use new transaction infrastructure to handle sets") tanıtıldı, v3.16-rc1'den beri mevcut — yani neredeyse on yıllık kernel'ler etkilendi. ZDI bunu ZDI-CAN-17470 (Team Orca of Sea Security) olarak izledi.
Detection¶
- Cross-table set reference'larından sonra tablo delete/dump sırasında
nft_setobject'leri üzerinde KASAN use-after-free. - Bir set'in isme göre arandığı ve çözülen set'in tablosunun reference eden object'in tablosundan farklı olduğu transaction'ları denetleme.
Mitigation¶
- Fix, reference edilen set'lerin aynı tabloya ait olmasını zorunlu kılar (cross-table set reference'larını reddeder/engeller); böylece bir set canlı bir reference'ın altından free edilemez. Düzeltme, SET_ID çözümüne eksik tablo eşitliği kontrolünü (
set->table == table) ekler, böylece bir batch artık başka bir tablodaki set'i refer edemez. 6.0-rc1'de ve stable backport'larda yamalandı. CAP_NET_ADMINdayanağını kaldırmak için unprivileged user namespace'leri kısıtlayın (user.max_user_namespaces=0).