Skip to content

Sequoia size_t-to-int mountinfo path overflow (CVE-2021-33909)

Linux'un seq_file path handling'indeki bir size_t-to-int dönüşümü, unprivileged bir user'ın çok-gigabyte'lık bir directory path'inin mount entry'sini okuyarak out-of-bounds bir kernel write sürmesine ve local root elde etmesine izin verir.

Mechanism

Note

İhlal edilen invariant şu: "pointer aritmetiğinde kullanılan bir length, buffer'ın sadık, non-negatif bir ölçüsü olarak kalmalı." fs/seq_file.c içinde, seq buffer'ı /proc/self/mountinfo'nun bir satırı gibi bir entry render edilirken gerektiğinde büyür (vmalloc ile, ikiye katlanarak). Bir path'in unsigned 64-bit size_t length'i INT_MAX'i aşabilir; boyutu signed int olarak ele alan seq_read/dentry_path gibi helper'lara aktığında değer negatife wrap eder. Sonraki prepend/copy mantığı o zaman allocate edilmiş buffer'ın başlangıcından çok önce bir hedef hesaplar ve oraya yazar — bir vmalloc'lı bölgenin altına kontrollü bir out-of-bounds write.

Qualys (buna "Sequoia" adını verenler) toplam length'i ~1GB'ı aşan bir directory path inşa edip ardından onun mountinfo satırını okuyarak kernel'in 10-byte'lık "//deleted" string'ini buffer base'inden yaklaşık -2GB-10B'lik bir offset'e yazdığını gösterdi. Bug 2014'te eklendi (commit 058504ed, "fs/seq_file: fallback to vmalloc allocation") ve 3.16'dan 5.13.4 öncesi 5.13.x'e kadarki kernel'leri etkiler.

Walkthrough

Public Qualys advisory'si trigger'ı, devasa bir path inşa etmek, onu mountinfo'da görünecek şekilde mount etmek ve sonra okumak olarak tarif eder.

Kavramsal trigger (yalnızca mantıksal)
1. In an unprivileged user namespace, mkdir a deeply nested chain of
   directories so the cumulative path length grows past 1 GB.
2. bind-mount (or FUSE-mount) that path so it produces a mountinfo line
   whose rendered length exceeds INT_MAX.
3. open("/proc/self/mountinfo") and read it, forcing seq_file to render
   the oversized path.
4. The size_t->int wrap makes prepend() write "//deleted" out of bounds,
   below the vmalloc buffer.

Mantıksal adımlar:

  1. 1GB'lık iç içe directory yapısını oluştur (unprivileged user namespace'ler bunu root olmadan erişilebilir kılar).

  2. Path'in /proc/self/mountinfo'ya yansıması için onu mount et.
  3. Rendering'i ve wrap'i sürmek için mountinfo'yu oku.
  4. Out-of-bounds write'ı kernel state'inin kontrolüne dönüştür. Qualys bunu root'a ulaşmak için başka primitive'lerle birleştirdi; escalation pattern'i için arbitrary-write-primitive ve commit-creds'e bak.

Detection

  • Aşırı derin directory hiyerarşileri ya da 1GB'a yakın/üzeri length'te path oluşturan process'ler için alert ver — normal workload'lar için anormaldir.
  • Unprivileged user-namespace oluşturmayı (CLONE_NEWUSER ile unshare/clone) takip eden mount etkinliğini ve /proc/self/mountinfo okumalarını monitor et.
  • Falco/auditd kuralları (Sysdig Sequoia'ya özgü Falco kuralları yayınladı) deep-mkdir-sonra-mount pattern'ini işaretleyebilir.
  • KASAN kernel'leri seq_file rendering path'lerindeki OOB write'ı raporlar.

Mitigation

Warning

Tek tam fix patch'lemektir: fs/seq_file.c'deki size_t/int handling'i düzelten bir kernel'e (>= 5.13.4 ya da bir backport) güncelle. Qualys'in listelediği sysctl mitigation'ları yalnızca kendi spesifik exploit chain'lerini engeller, alttaki bug'ı değil.

  • Kısmi, exploit'e özgü hardening: unprivileged-namespace path'ini kaldırmak için kernel.unprivileged_userns_clone=0 (desteklenen yerlerde) ve yaygın bir escalation yardımcısını kaldırmak için kernel.unprivileged_bpf_disabled=1 ayarla.
  • Defense-in-depth: slab-freelist-hardening, KASLR ve SMAP/SMEP, OOB write'ı code execution'a dönüştürmenin maliyetini artırır.

References