shiftfs double free (CVE-2021-3492)¶
Ubuntu'nun out-of-tree shiftfs'i, btrfs ioctl'lerini alttaki filesystem'e geçirirken bir copy fault'u yanlış ele alır; cleanup path'ini iki kez çalıştırır ve local privilege escalation için kernel object'lerini double-free eder.
Mechanism¶
Note
İhlal edilen invariant şu: "bir error/cleanup path'i ile success path'i aynı object'i birlikte release etmemeli." shiftfs belirli btrfs ioctl'lerini proxy'lediğinde kernel object'leri (file descriptor'lar / memdup_user ile heap buffer'ları) allocate eder ve bir copy_*_user fault'unda error handling içinde restore/cleanup helper'ını (shiftfs_btrfs_ioctl_fd_restore) çağırır — ama ana fonksiyon sonra aynı cleanup'ı tekrar çalıştırır. Sonuç, kfree/__close_fd'nin aynı object'ler üzerinde iki kez yürümesidir: bir double-free. Bir double-free, attacker'ın tek bir slab object'ine iki referans elde etmesine ve reallocation'dan sonra use-after-free-tarzı kontrollü bir örtüşmeye (overlap) izin verir.
shiftfs, unprivileged user'ların mount edebileceği (ör. container'lar / user namespace'ler içinde) Ubuntu'ya özgü bir stacking filesystem olduğundan, açık veren ioctl path'i etkilenen Ubuntu kernel'lerinde root olmadan erişilebilirdir.
Walkthrough¶
Bu, ZDI'nin Pwn2Own Vancouver 2021'inde (ZDI-CAN-13562) bir local privilege escalation olarak gösterildi.
Kavramsal fault-injection şekli
1. Mount shiftfs (reachable from an unprivileged/container context).
2. Issue a btrfs passthrough ioctl that shiftfs marshals via memdup_user.
3. Arrange copy_to_user to fault mid-operation (e.g., userfaultfd-backed
destination) so the error path runs the fd-restore/cleanup helper...
4. ...and then the main function runs the SAME cleanup again -> double free.
Fix'in şekli (public write-up'tan)
Mantıksal escalation: double-free edilmiş object attacker-kontrollü data ile reclaim edilir ve hassas bir yapıyla örtüştürülür (public write-up bir function pointer'ı corrupt etmek için bir sysctl table'ı hedefler); bu da KASLR/SMAP'i bypass ederken arbitrary read/write ve code execution verir. arbitrary-write-primitive ve cross-cache-attack'e bak.
Detection¶
shiftfs'i mount edip hemen btrfs ioctl'leri veren unprivileged/container process'leri için alert ver — normal workload'lar için atipiktir.- Güvenilmeyen process'ler tarafından
userfaultfdkullanımı, double-free/UAF race'leri için güçlü bir fault-injection sinyalidir; gerekmediği yerde logla. - KASAN kernel'leri shiftfs ioctl path'lerinde "double-free" / "invalid-free" splat'ları üretir.
- Tek bir process/container'a kümelenmiş kernel slab corruption uyarıları ya da oops'ları için monitor et.
Mitigation¶
Warning
Ubuntu'nun fix'ini uygula: USN-4917-1 uyarınca linux 5.4.0-72.80 (Focal) / 5.8.0-50.56 (Groovy) ya da sonrasına güncelle. Patch, fd-restore cleanup'ının tam olarak bir kez çalışmasını sağlar.
- shiftfs gerekli değilse, attack surface'ı kaldırmak için modülü blacklist'e al/unload et (
modprobe -r shiftfs; blacklist'e al); shiftfs Ubuntu'ya özgüdür ve 18.04 ile 21.04+ üzerinde yoktur. - Onu kimin mount edebileceğini sınırlamak için unprivileged user namespace'leri kısıtla (
kernel.unprivileged_userns_clone=0). - Defense-in-depth: slab-freelist-hardening ve freelist randomization, double-free'yi silah haline getirmenin maliyetini artırır.