Skip to content

Hardened usercopy

Linux CONFIG_HARDENED_USERCOPY, her copy_to_user / copy_from_user'ı slab object'inin whitelist'lenmiş region'ına, stack frame'ine ve kernel text/rodata'sına karşı bounds-check eder; böylece buggy bir copy komşu belleğe over-read veya over-write yapamaz.

Mechanism

copy_to_user() / copy_from_user(), user/kernel sınırı boyunca arbitrary-length buffer'ları taşır. Bir uzunluk veya pointer attacker'ın etkisindeyse, bir copy amaçlanan object'inin sonunu aşabilir ve komşu kernel belleğini açığa çıkarabilir (over-read) ya da corrupt edebilir (over-write) — klasik bir information-leak ve heap-corruption primitive'i.

Hardened usercopy, böyle her copy'ye bir check araya sokar. Whitelisting uzantısı (grsecurity/PaX PAX_USERCOPY'den David Windsor tarafından port edildi, Kees Cook tarafından review edildi), bir slab cache'in object'lerinin içinde bir usercopy region declare etmesine izin verir: kmem_cache_create_usercopy() bir useroffset (kopyalanabilir pencerenin başladığı yer) ve bir usersize (uzunluğu; 0 bu cache'ten hiç kopyalamaya izin verilmediği anlamına gelir) alır.

Invariant hardened usercopy enforces

Slab allocator'ından elde edilen bir object bir user-space copy fonksiyonuna geçirildiğinde, kopyalanacak alan tamamen whitelist'lenmiş pencerenin içinde [useroffset, useroffset + usersize) yer almalıdır. Object sınırını geçecek, yanlış region'a yayılacak veya bir usersize == 0 cache'ten kaynaklanacak herhangi bir copy reddedilir (kernel usercopy: kernel memory ... raporlar ve BUG verir). Check şunları da kapsar:

  • slab object'leri — copy, object'in usercopy region'ı içinde kalmalı;
  • stack — copy, mevcut stack frame içinde olmalı, ondan taşmamalı;
  • kernel text / rodata.text/.rodata ile çakışan copy'ler yasaktır, çünkü bunlar asla meşru copy kaynağı/hedefi değildir.

Her object yalnızca tek bir region expose edebilir, bu da driver'ları user-expose edilen field'ları bir arada gruplamaya zorlar. Whitelisting serisinden sonra, taze bir boot'ta slab-cache belleğinin ~%15'inden azı usercopy bug'larına expose kalır.

GFP_USERCOPY / dedike usercopy slab'leri, heap-layout saldırılarını zorlaştırmak için user-expose edilen object'leri daha da izole eder.

Walkthrough

1. Özelliğin build içinde olduğunu doğrula.

$ zgrep HARDENED_USERCOPY /proc/config.gz
CONFIG_HARDENED_USERCOPY=y

2. Gerçek bir whitelist annotation'ı oku. userspace'e veri expose eden cache'ler pencerelerini açıkça declare eder, ör. mimari başına FPU/task_struct cache'leri kmem_cache_create_usercopy(name, size, align, flags, useroffset, usersize, ctor) çağırır. kmem_cache_create() ile oluşturulan generic bir cache'in usersize == 0'ı vardır, dolayısıyla byte'larından herhangi birini userspace'e/userspace'ten kopyalamak reddedilir.

3. Bir reddi gözlemle. Whitelist'lenmiş region'ı aşan bir copy, suçlu task'ı bir raporla abort eder:

usercopy violation report
usercopy: Kernel memory overwrite attempt detected to slab 'kmalloc-512'
          (offset 480, size 64)!
------------[ cut here ]------------
kernel BUG at mm/usercopy.c:NNN!
...
Call Trace:
 usercopy_abort+0x...
 __check_heap_object+0x...
 __check_object_size+0x...
 copy_to_user+0x...

Whitelisting depends on correct annotations

Check yalnızca annotate edilmiş olanı korur. Eksik bir whitelist tarihsel olarak amaçlanan field aralığı yerine tüm slab allocation boyutunu check etmeye geri düşerdi (CONFIG_HARDENED_USERCOPY_FALLBACK, açığı işaretlemek için bir WARN() ile), ki bu sıkı bir usersize'dan daha zayıftır. Ayrıca aşırı geniş bir whitelist'in içinde kalan bir copy'yi de yakalamaz.

Detection

Bir ihlal kendi kendini raporlar: __check_object_size() / __check_heap_object(), task'ı öldürmeden önce cache adını, offset'i ve boyutu loglayan usercopy_abort()'u çağırır — hem bir runtime savunması olarak hem de fuzzing sırasında bir driver'ın bir copy'yi yanlış boyutlandırdığına dair bir sinyal olarak faydalıdır.

Mitigation

SMAP (ki kernel'in user page'lere istenmeyen erişimini tümden bloklar), slab hardening (slab freelist hardening) ve init-on-alloc ile eşleştir; böylece leak'lenen bir region'ın neyi açığa çıkarabileceğini azalt.

References