Malicious filesystem image mount attack surface¶
Attacker-crafted bir filesystem image'i mount etmek, in-kernel on-disk parser'ı hostile superblock/inode/extent metadata'sı üzerinde çalıştırır — userns + FUSE/loop ve removable-media automount ile unprivileged erişilebilen, syzkaller'ın sürekli beslediği yoğun bir ring0 bug kaynağı.
Mechanism¶
Her filesystem driver, on-disk structure'ları (superblock, block/inode bitmap, directory entry, B-tree/extent node, journal) parse eden bir kod yolu içerir. Bu kod tarihsel olarak güvenilen bir invariant üzerine yazıldı: "disk'teki metadata, kendi mkfs'imizin ürettiği geçerli bir image'dir." Bir image attacker tarafından craft edildiğinde o invariant düşer ve length/offset/count field'ları artık trust edilemez.
Note
Bug class'ı şudur: on-disk'ten okunan bir değer (bir key length, bir extent count, bir directory record boyu, bir bitmap index) sonraki bir memory işlemini boyutlandırmak/indexlemek için kullanılır ama allocation sınırına, blok boyutuna ya da array cap'ine karşı validate edilmez. Sonuç OOB read/write, UAF ve integer overflow'dur — hepsi ring0'da, çünkü parser fully privileged kernel context'inde koşar. Boundary "untrusted disk data → trusted kernel struct" sınırında geçilir; kernel'in her hfs_bnode_read_u16(), le32_to_cpu(ext->count) çağrısı bir trust-boundary crossing'idir.
Warning
Kritik nokta kim mount edebilir'dir. Klasik varsayım "image mount etmek CAP_SYS_ADMIN ister, yani local + privileged, yani düşük risk"tir. İki gelişme bunu bozar: (1) unprivileged user namespace içinde bir process kendi userns'inde CAP_SYS_ADMIN kazanır ve FUSE gibi bazı filesystem'leri userns'ten mount edebilir; (2) desktop automount (udisks2 + polkit) console user'ının takılan removable media'yı initial namespace'te explicit CAP_SYS_ADMIN tutmadan mount etmesine izin verir. Böylece "physical access / privileged" varsayımı, "USB tak" ya da "unprivileged process"e iner.
Neden bu surface bu kadar yoğun: syzkaller/syzbot mounted image'leri iki boyutta fuzz'lar — hem image byte'larını hem de mount sonrası syscall'ları mutate eder. Nadir/legacy parser'lar (hfs+, hfs, udf, f2fs, ntfs3, jfs, reiserfs, ufs, squashfs, minix) az test edilmiş fakat build'lerde enabled kaldığı için düşük asılı meyve olur.
Walkthrough¶
Kavramsal reprodüksiyon; herhangi bir parser bug'ı için ortak iskelet (concrete örnek: HFS+ CVE-2025-0927, ayrıca bkz. sibling not):
- Surface seç. Hedef distro'da mount edilebilen ama az test edilmiş bir filesystem type seç (nadir on-disk format = daha zayıf validation).
- Image craft et. Geçerli bir base image'i
mkfsile üret, sonra tek bir metadata field'ı hedefle: bir key/record length'i, bir extent/entry count'unu ya da bir offset'i allocation'ı aşacak şekilde patch'le. Amaç parser'ın early sanity check'lerini geçip vulnerable read/copy'ye ulaşmaktır. - Mount tetikle. Image'i loop device üzerinden mount et, ya da automount tetiklesin diye media tak, ya da uygun tipse userns + FUSE üzerinden mount et. Mount sırasında superblock/tree parse çalışır ve hostile field consume edilir.
- Boundary cross. Unvalidated field OOB write/read ya da UAF'e dönüşür. Bu tek başına bir memory-corruption primitive'idir; onu LPE'ye çevirmek image bug'ından bağımsız, standart slab/heap exploitation'dır ve bu katalogda ayrı tutulur.
Kavramsal fragment — validate edilmeyen on-disk length
Gerçek bug'larda pattern aynıdır; sadece field ve struct değişir (extent count, dir reclen, bitmap index...).Detection¶
- KASAN / KFENCE: debug kernel'de bug tam olarak parser fonksiyonunda patlar (
*_read_key,*_bread,ext4_*,ntfs_*), slab-out-of-bounds ya da use-after-free olarak. syzbot report'ları bu imzayı taşır. - Mount telemetry: untrusted/removable bir source'un nadir bir filesystem type ile mount edilmesi gözlemlenebilir bir olaydır.
auditdilemountsyscall'ını vefstype'ı logla; udisks2/systemd-udevd automount event'lerini izle; beklenmedikfstype=hfsplus|udf|jfs|...bir sinyaldir. - Crash pattern: removable media insertion ya da unprivileged mount denemesiyle korele olan kernel oops/panic (özellikle bir fs modülünün ilk kez load olması).
- Module load: normalde hiç kullanılmayan bir filesystem modülünün (
modprobe hfsplus) autoload edilmesi;/proc/modulesve module autoload audit'i bunu yakalar.
Mitigation¶
- Nadir filesystem'leri kaldır/blokla. İhtiyaç duyulmayan on-disk parser'ları autoload edilemez yap:
install <fs> /bin/falseya dablacklist <fs>(/etc/modprobe.d/). CIS benchmark'ları tam da bunu önerir (cramfs, freevxfs, hfs, hfsplus, jffs2, squashfs, udf...). Build kontrolün varsa ilgiliCONFIG_*_FS'i tamamen disable et. - Automount'u kıs. udisks2/polkit removable-media mount policy'sini bir allow-list'e daralt; kiosk/server rollerinde automount'u kapat. Air-gapped transfer host'larında image'i mount etmeden, userspace tool ile parse et.
- userns'i hardening'le. Gerekmiyorsa unprivileged user namespace'i kapat (
kernel.unprivileged_userns_clone=0Debian/Ubuntu'da, ya dauser.max_user_namespaces=0); AppArmorusernsmediation kullan. Bu, userns+FUSE üzerinden ulaşılabilen parser surface'ini keser. - seccomp / sandbox. Container ve sandbox profillerinde
mount/move_mount/fsopen/fsconfigsyscall'larını blokla; böylece process kendi image'ini mount ettiremez. - Patch + fuzz-hardening. Distro kernel'lerini güncel tut; syzbot'un mounted-image bug'ları için üretilen fix'ler hızlı akar. Maintainer'lar (örn. XFS) fstests içinde image-fuzzing suite tutarak parser'ları proaktif sertleştiriyor — LWN'deki responsible-disclosure tartışması bu trade-off'u özetler.