Skip to content

nft_pipapo inactive element UAF (CVE-2023-6817)

nft_pipapo_walk() inactive set element'lerini atlamadığı için tek bir transaction aynı element'i iki kez deactivate edebilir — bu double-deactivation, destroy worker çalıştığında bir slab use-after-free'e dönüşür.

Mechanism

Note

nf_tables'te NFT_MSG_DELSETELEM bir element'i hemen free etmek yerine deactivate eder (next-generation active flag'ini temizler); gerçek free işlemi daha sonra, commit'ten sonra nf_tables_trans_destroy_work() içinde gerçekleşir. Bir set walk'unun uyması gereken invariant, current generation'da active olmayan element'leri atlamaktır. pipapo walk bunu görmezden geldi.

nft_pipapo_walk() (net/netfilter/nft_set_pipapo.c) her element üzerinde iter->genmask'i kontrol etmeden iterate ediyordu. Yani tek bir transaction içinde NFT_MSG_DELSETELEM'i iki kez göndermek her element'i iki kez deactivate eder; ikinci deactivation zaten destruction için kuyruğa alınmış bir element üzerinde çalışır ve destroy worker onu free ettiğinde bir slab UAF ortaya çıkar.

Kardeş bug'tan farkı

Bu, nft_pipapo_walk()'un inactive element'leri atlamamasından kaynaklanan bir use-after-free (CVE-2023-6817, walk → double-deactivation). Aynı nft_set_pipapo type'ındaki diğer bug — netfilter nf_tables double-free OtterRoot (CVE-2024-26809) — ise match/clone view paylaşımından doğan bir double-free'dir; farklı kök neden, farklı CVE, farklı fix commit'i.

Walkthrough

Fix, walk callback'i çağırmadan önce bir active-check ekler:

/* in the pipapo walk loop, before iter->fn(...) */
if (!nft_set_elem_active(&e->ext, iter->genmask))
        goto cont;

Kavramsal reproduction (reporter'ın PoC'u; CAP_NET_ADMIN gerektirir, user namespace'ler üzerinden erişilebilir):

  1. Bir pipapo set oluştur (concatenated-range set type'ı).
  2. Tek bir transaction içinde, aynı element üzerinde NFT_MSG_DELSETELEM'i iki kez gönder.
  3. Her iki deactivation da başarılı olur; destroy worker daha sonra zaten referans verilmiş bir object'i free eder → slab use-after-free (v6.7-rc4'te nf_tables_trans_destroy_work() içinde KASAN "slab-use-after-free").

Rapordaki build satırı:

gcc -o poc poc.c -lnftnl -lmnl

Warning

Bug, pipapo set type'ı tanıtıldığından beri (3c4287f62044) mevcut; Xingyuan Mo (IceSword Lab) tarafından raporlandı.

Detection

  • pipapo set'lerine bağlı olarak nf_tables_trans_destroy_work() içinde KASAN slab-use-after-free.
  • Tek bir batch içinde aynı element'in double DELSETELEM'i anormaldir.

Mitigation

  • v6.7-rc5 öncesinde 317eb9685095678f2c9f5a8189de698c5354316a commit'iyle düzeltildi ("netfilter: nft_set_pipapo: skip inactive elements during set walk"). ~5.6'dan 6.7'ye kadar etkiledi.
  • Local erişimi ortadan kaldırmak için unprivileged user namespace'leri devre dışı bırak.

References