Skip to content

io_uring provided-buffer spray

io_uring provided buffer'ları kullanarak küçük bir kmalloc cache'inde çok sayıda kontrollü io_buffer object'i allocate et — free edilmiş slot'ları reclaim etmek için kullanışlı bir heap-spray primitive.

Mechanism

io_uring, bir uygulamanın kernel'a önceden buffer havuzları vermesine izin verir. Klasik provided buffer'lar IORING_OP_PROVIDE_BUFFERS opcode'uyla eklenir; ring-tabanlı provided buffer'lar ise IORING_REGISTER_PBUF_RING ile register edilir. Klasik provided buffer eklemek, kernel'ın bunları izlemek için struct io_buffer object'leri allocate etmesine yol açar.

Note

Her provided buffer küçük bir io_buffer kernel object'iyle izlenir (&bl->buf_list üzerinden bağlanır). Attacker kaç buffer sağlayacağını ve hangi adres/uzunlukla sağlayacağını seçtiğinden, bu küçük bir cache'te kontrol edilebilir bir allocation'dır (io_buffer'ın kmalloc-32'ye düştüğü dokümante edilmiştir — ancak kesin cache, struct io_buffer'ın boyutuna bağlı olarak kernel sürümüne/config'e göre değişebilir; hedef kernel'da assume etmek yerine doğrulanmalıdır). Bu da onu temiz bir reclaim/spray primitive yapar: bir victim object'i free et, sonra slab'i yeniden doldurmak için buffer sağla ve free edilmiş slot'un üzerine io_buffer'ları bindir.

Warning

Spray'in işe yaraması hedef object'in boyutunun io_buffer cache'iyle eşleşmesine bağlıdır. Diğer boyutlar için ring-tabanlı provided buffer'lar (IORING_REGISTER_PBUF_RING) bunun yerine page-backed ring'ler allocate eder; bu farklı (page-level) bir primitive'dir — bkz. io_uring provided-buffer ring UAF.

Walkthrough

Klasik provided buffer'larla kavramsal spray akışı:

  1. Bir io_uring instance'ı kur (io_uring_setup).
  2. Bir buffer sayısı, bir uzunluk, bir buffer group id ve bir başlangıç buffer id'si belirten IORING_OP_PROVIDE_BUFFERS SQE'leri submit et; kernel ilgili io_buffer object'lerini allocate eder.
  3. Bunu aynı cache'teki bir victim object'i free ettikten hemen sonra kullan ki allocator free edilmiş slot'u attacker kontrolündeki io_buffer'lar için yeniden kullansın.
  4. Bir info-leak veya overwrite primitive'iyle eşleştir: örneğin içeriğini attacker'ın kontrol ettiği, dangling bir reference ile örtüşen bir object.

Bu spray birçok io_uring exploit'inde bir yapı taşı olarak görünür ve io_buffer gibi küçük-cache object'lerinin tercih edilen reclaim hedefleri olmasının sebeplerinden biridir.

Detection

Unprivileged bir task'tan gelen yüksek hacimli IORING_OP_PROVIDE_BUFFERS submission'ları veya kmalloc-32'de çok sayıda io_buffer allocation'ı gözlemlenebilir. Spray'in exploit etmek için kullanıldığı UAF'ı KASAN yakalar.

Mitigation

Unprivileged io_uring'i kısıtlamak (/proc/sys/kernel/io_uring_disabled) spray surface'ini ortadan kaldırır. Slab hardening (CONFIG_SLAB_FREELIST_RANDOM, dedicated/random kmalloc cache'ler) io_buffer'ın seçilmiş bir victim slot'una deterministik örtüşmesini azaltır.

References