ExpRace interrupt-raising kernel race¶
Userspace'in, racing bir thread'i çalıştıran core'da kasıtlı olarak bir inter-processor interrupt yükseltmesini sağla; onu IPI/IRQ handler'a sokarak başka türlü kazanılamaz bir race window'unu uzat.
Mechanism¶
Note
Birçok kernel race'inin minik bir window'u vardır. ExpRace (Lee, Min, Lee — USENIX
Security 2021), iki racing access'in interleave olması ve thread 1'in window'unun thread
2'ninkinden daha uzun sürmesi gereken multi-variable race'leri hedefler; |T1| < |T2|
olduğunda brute force başarısız olur (paper, brute force'a 24 saat direnen race'lerden
bahseder). Asıl içgörü: bir interrupt kullanarak race window'unu kasıtlı olarak
büyütmek. Window içindeki preemption onu genişletirdi, ama kullanıcılar preemption'ı
kontrol edemez ya da doğrudan interrupt yükseltemez — bu yüzden ExpRace, userspace'in bir
hedef CPU core'una doğru anda bir interrupt aldırması için dört dolaylı yol bulur ve
racing thread'i TExtend kadar geciktirerek |T1 + TExtend| > T2 yapar.
Window timeline (kavramsal; süreler kernel/donanıma göre değişir):
Baseline ( |T1| < |T2| → brute force başarısız ):
T1 (thread 1) |==| window çok kısa, T2'yi kapsamaz
T2 (thread 2) |=========|
ExpRace ( interrupt T1'i TExtend kadar uzatır → |T1 + TExtend| > |T2| ):
T1 (thread 1) |==|####### TExtend #######| interrupt handler T1'i bekletir
T2 (thread 2) |=========| artık iki window örtüşür → race kazanılır
^
interrupt (IPI / IRQ) hedef core'a gelir
Walkthrough¶
Üç task: Taskx/Tasky racing syscall'ları çağırır; Taskint racing thread'i çalıştıran
core'da interrupt'ı ateşler. Dört interrupt mekanizması (paper Table 2):
| Interrupt | Userspace tetikleyici | Hedefleme state'i | Gereksinim |
|---|---|---|---|
| Reschedule IPI | sched_setaffinity() (smp_send_reschedule(cpu)'yu sürer) |
scheduler | CPU pinning |
| Func-call IPI (TLB shootdown) | mprotect() / munmap() |
mm_struct.cpu_bitmap |
paylaşılan mm |
| Func-call IPI (membarrier) | membarrier() |
mm_struct.membarrier_state |
paylaşılan mm |
| HW interrupt | socket()/connect() ile TCP, ya da disk I/O |
device IRQ affinity | CPU pinning |
Hardware-interrupt yöntemi için, bir device'ın IRQ'sine hangi core'un hizmet ettiğini
öğrenmek üzere /proc/irq/#/smp_affinity'yi oku, task'ları buna göre pinle, sonra bir network
isteğini öyle zamanla ki NIC'in IRQ'si victim'in window'unun içine düşsün — o core'u IRQ
handler'a sokarak racing thread'den uzaklaştırır.
Warning
Paper'ın değerlendirmesinde hardware interrupt yöntemi 10 gerçek-dünya race'inin
hepsini exploit etti (TLB shootdown 7/10; membarrier en zayıf), HW interrupt'lar için
ölçülen ~14,103 cycle'lık bir uzatmayla — en büyük TExtend, ve window büyüdükçe neden
güvenilir kaldığı. Baseline brute force 24 saatte 10'unu da başaramadı. Teknik ayrıca
Windows'a (SetThreadAffinityMask) ve macOS'a da genelleşti.
Mitigation¶
Race'lerin kendisi düzeltilmelidir (doğru locking); ExpRace bir window-widening
primitive'idir, bir güvenlik açığı değil. sched_setaffinity/IRQ-affinity bilgisinin
granülerliğini azaltmak, ya da critical section'lar içindeki preemption'ı daha az
gözlemlenebilir kılmak çıtayı yükseltir ama kanalı kaldırmaz.