init_on_alloc¶
Page-allocator ve slab belleğini allocation zamanında sıfırlayan ve uninitialized-heap-memory information leak'lerinin büyük bir sınıfını ortadan kaldıran Linux boot-time hardening'i.
Mechanism¶
init_on_alloc, CONFIG_INIT_ON_ALLOC_DEFAULT_ON Kconfig seçeneği ve init_on_alloc=1 kernel command-line parametresi ile kontrol edilir (init_on_alloc=0 ile devre dışı bırakılır). CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y ayarlamak, default olarak command line'a init_on_alloc=1 koymakla aynı etkiyi yaratır.
Etkinleştirildiğinde, tüm page-allocator ve SL[AU]B (slab) allocation'ları çağırana geri verilmeden önce sıfırlarla doldurulur. Özellik Linux v5.3'te merge edildi (Alexander Potapenko'nun çalışması, Kernel Self-Protection Project / Kees Cook altında gözden geçirildi). grsecurity/PaX PAX_MEMORY_SANITIZE'ın upstream torunudur.
Invariant enforced
Page allocator veya slab allocator tarafından döndürülen herhangi bir belleğin sıfırlarla initialize edilmiş olması garanti edilir. Bir allocation'ı tam doldurmadan önce userspace'e kopyalayan bir kernel code path'i bu yüzden eski heap içeriği yerine sıfırları leak eder ve o allocation için "uninitialized heap memory" infoleak primitive'ini ortadan kaldırır.
Performans etkisi workload'a göre değişir; çoğu durumda etki <%1'dir, ancak bazı sentetik workload'larda %7'ye kadar ölçülmüştür. init_on_alloc yalnızca yakında kullanılacak (ve dolayısıyla zaten cache'e çekilecek) belleğe dokunduğundan, init_on_free'den belirgin biçimde daha ucuzdur.
Walkthrough¶
Enable and verify
Parametreyi kernel command line'a ekle (örn. GRUB GRUB_CMDLINE_LINUX üzerinden):
Çalışma zamanında aktif olduğunu doğrula:
Derlemeye gömülü default'u kontrol et:
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y olduğunda, init_on_alloc=0 ile açıkça kapatılmadıkça özellik açıktır.
Scope
init_on_alloc belleği yalnızca allocation zamanında sıfırlar. Bir free'den sonra hassas verinin ömrünü kısaltmaz; bunun için onu init_on_free ile eşleştir. Ayrıca allocator granülarlığında (page/slab) çalışır, dolayısıyla uninitialized stack değişkenlerini ele almaz — stack-variable-auto-init ve structleak-structure-auto-init gibi compiler güdümlü auto-init'e bak.
Beklenen etki: bir kmalloc()'lanmış yapıyı her alanı initialize etmeden copy_to_user() yapan bir driver bug'ı, artık o slab nesnesini daha önce ne dolduruyorsa onun yerine set edilmemiş alanlar için sıfır byte açığa çıkarır.
Detection¶
Tespit edilecek çalışma zamanı "saldırısı" yoktur; hardening'in varlığı /proc/cmdline ve kernel config üzerinden gözlemlenebilir. Önceden var olan uninitialized-memory bug'ları, bug yerine semptomu (leak'i) maskeleyen init_on_alloc'a güvenmek yerine, geliştirme zamanında KMSAN/MSAN tarzı instrumentation ile en iyi şekilde yüzeye çıkarılır.