Skip to content

Timer subsystem arbitrary read (CVE-2017-18344)

Out-of-range bir sigev_notify ile bir POSIX timer oluştur, ardından /proc/PID/timers'ı okuyarak show_timer()'ın global bir string array'i out of bounds indekslemesini ve kernel memory sızdırmasını sağla.

Mechanism

Note

Bu, POSIX timers subsystem'inde (kernel/time/posix-timers.c) bir out-of-bounds (global) read'dir. Bir kullanıcı timer_create() ile bir timer oluşturur ve sigev_notify field'ı signal-delivery modu olan bir struct sigevent geçirir. good_sigevent()'teki sanity check yalnızca SIGEV_THREAD_ID path'ini doğruluyordu; SIGEV_THREAD_ID set edilmediğinde, değeri legal kümeyle kısıtlamak yerine herhangi bir arbitrary sigev_notify değerini kabul ediyordu. Saklanan, doğrulanmamış değer daha sonra show_timer() içinde (/proc/PID/timers okunarak erişilir) küçük bir global method string array'ini indekslemek için kullanılır: nstr[notify & ~SIGEV_THREAD_ID]. Büyük, özel hazırlanmış bir sigev_notify, indeksi array sonunun ötesine taşır ve kod out-of-bounds global memory'den pointer boyutunda bir değeri dereference ederek onu /proc çıktısına sızdırır.

Walkthrough

  1. ev.sigev_notify'ı büyük bir değere (legal aralığın dışında; bozuk validation path'inin alınması için SIGEV_THREAD_ID'yi clear bırak) set ederek struct sigevent ev oluştur.
  2. timer_create(clockid, &ev, &timerid)good_sigevent() kötü değeri reddetmeyi başaramaz, böylece timer attacker'ın kontrol ettiği notify değeri saklanmış halde oluşturulur.
  3. /proc/<pid>/timers'ı oku; bu show_timer()'ı çağırır.
  4. show_timer() içinde, sorunlu nstr[notify & ~SIGEV_THREAD_ID] indeksi, global notify-method string array'inin ~8 byte dışını okur; değer proc çıktısına render edilerek kernel memory sızdırılır.
  5. Komşu kernel memory'de gezinmek için farklı sigev_notify değerleriyle tekrarla — KASLR'ı yenmek veya hassas veri sızdırmak için faydalı.

Warning

Yalnızca hem CONFIG_POSIX_TIMERS hem CONFIG_CHECKPOINT_RESTORE ile derlenmiş kernel'leri etkiler (ikincisi /proc/PID/timers'ı expose eder). 57b8015e commit'i (3.10) ile getirildi, cef31d9af908 commit'i ("posix-timer: Properly check sigevent->sigev_notify", 4.15-rc4) ile düzeltildi.

Detection

Out-of-range sigev_notify değerleri taşıyan anormal timer_create kullanımıyla birlikte /proc/*/timers'a yapılan unprivileged read'leri izle.

Mitigation

  • good_sigevent()'te legal sigev_notify modlarını doğrulayan kernel ≥ 4.15-rc4'e (veya cef31d9af908'in backport'una) güncelle.
  • Mümkünse, /proc/PID/timers expose'unu kaldırmak için CONFIG_CHECKPOINT_RESTORE olmadan derle.

References