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:
-
1GB'lık iç içe directory yapısını oluştur (unprivileged user namespace'ler bunu root olmadan erişilebilir kılar).
- Path'in
/proc/self/mountinfo'ya yansıması için onu mount et. - Rendering'i ve wrap'i sürmek için mountinfo'yu oku.
- 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_NEWUSERileunshare/clone) takip eden mount etkinliğini ve/proc/self/mountinfookumaları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çinkernel.unprivileged_bpf_disabled=1ayarla. - Defense-in-depth: slab-freelist-hardening, KASLR ve SMAP/SMEP, OOB write'ı code execution'a dönüştürmenin maliyetini artırır.