Skip to content

netfilter nf_tables double-free OtterRoot (CVE-2024-26809)

pipapo set destroy path'i, hem priv->match'te hem de priv->clone'da var olan element'leri free eder ve aynı chunk'ları double-free eder — OtterRoot exploit'i tarafından universal, symbol'süz bir root'a dönüştürüldü.

Mechanism

Note

nft_set_pipapo set type'ı, element'lerinin iki view'unu tutar: committed bir match ve çalışan bir clone. Invariant, her set element'inin bu iki view boyunca tam olarak bir kez kfree() edilmesi gerektiğidir. Bir set dead olarak işaretlendiğinde (set->dead), commit path priv->dirty'yi temizlemeyi atlar, böylece destroy path hem match'i hem de clone'u dolaşır ve paylaşılan element pointer'larını iki kez free eder.

Resmi kayıt fix'i belirtir: "release elements in clone only from destroy path … it is possible to destroy elements twice." clone, hem already-committed hem de not-yet-committed element'lerin bir view'unu tutar; dirty/clone bookkeeping'i olmadan destroy dolaşması double-free yapar.

Kardeş bug'tan farkı

Bu, match/clone view paylaşımından kaynaklanan bir double-free (CVE-2024-26809). Aynı nft_set_pipapo type'ındaki diğer bug — nft_pipapo inactive element UAF (CVE-2023-6817) — ise farklı bir kök neden taşır: nft_pipapo_walk()'un inactive element'leri atlamaması nedeniyle double-deactivation → use-after-free. İkisini karıştırmayın.

Walkthrough

İlk double-free kmalloc-256'ya düşer. OtterRoot (OtterSec / Pedro Pinto) onu universal bir LPE'ye çevirir:

  1. Tek bir kmalloc-256 chunk'ına iki reference almak için pipapo double-free'i tetikleyin.
  2. kmalloc-1k'ya ulaşmak için msg_msg->mlist.next'i manipüle ederek cross-cache pivot yapın.
  3. Bir pipe_buffer'ı kontrollü data ile overlap edin; onun page pointer'ını vmemmap_base'e hijack edin.
  4. Corrupt edilen pipe_buffer page pointer'ı üzerinden kernel-base imzasını tarayarak physical-KASLR hizalamasını brute-force edin — per-build symbol ya da ROP yok.
  5. Bir attacker-controlled binary'yi root olarak çalıştırmak için modprobe_path'i overwrite edin.

Warning

Kullanılan heap spray object'leri: msg_msg (hem 256-byte hem de 1k variant'ları) ve pipe_buffer. Exploit "universal"dır, çünkü kernel base'i hardcoded bir offset'e güvenmek yerine runtime'da keşfeder; OtterSec patch gap'ini kabaca iki ay boyunca bir 1-day olarak istismar etti.

Commit reference'ları (writeup'tan)
  • Tanıtıldı: 9827a0e6e23bf43003cd3d5b7fb11baf59a35e1e
  • set->dead enabler'ı: 5f68718b34a531a556f2f50300ead2862278da26
  • Düzeltildi: b0e256f3dd2ba6532f37c5c22e07cb07a36031ee (NVD ayrıca backport b36b83297ff4910dfc8705402c8abffd4bbf8144'ü listeler)
  • lonial con (kernelCTF) tarafından bulundu; OtterRoot universal exploit'i OtterSec tarafından.

Detection

  • nft_pipapo_destroy() / nft_set_pipapo_match_destroy() içinde KASAN double-free.
  • Bir unprivileged process'in pipapo set'leri (concatenated-range set'ler) hızlı art arda oluşturup destroy etmesi şüphelidir.

Mitigation

  • Patch'lenmiş kernel'ler clone element'lerini yalnızca destroy path'inden free eder. Etkilenen stable line'lar 5.10.130+ / 5.15.54+ / 6.1+'tan erken 6.8.x serisine kadar uzanır.
  • CAP_NET_ADMIN-in-netns reach'ini kaldırmak için unprivileged user namespace'leri devre dışı bırakın.

References