TOCTOU race against SMM CommBuffer (VU#434994)¶
Birçok SMI handler CommBuffer'ı bir kez doğrular ve ardından onu external pointer'dan yeniden okur; handler'la yarışan bir saldırgan, validation'ı yenmek için veriyi check ile use arasında değiştirebilir.
Mechanism¶
Invariant
Bir SMI handler için güvenli desen şudur: CommBuffer'ın SMRAM dışında olduğunu
doğrula (SmmIsBufferOutsideSmmValid), onu SMRAM-local belleğe kopyala ve
ardından yalnızca local kopya üzerinde çalış. Invariant: handler'ın üzerinde
işlem yaptığı her field, doğruladığı field olmalıdır. TOCTOU hatası (VU#434994,
"çeşitli UEFI implementasyonlarında TOCTOU kusurları nedeniyle çoklu race
condition"), handler üst seviye buffer'ı doğrulayıp/kopyalayıp ardından sonraki
field check'lerini local kopya yerine orijinal external pointer'a karşı yaptığında
ortaya çıkar. External buffer hâlâ saldırgan tarafından erişilebilir DRAM'de
yaşadığından, ikinci bir ajan (başka bir CPU thread'i ya da DMA-capable bir cihaz)
bu field'ları check'ten sonra ve use'dan önce değiştirebilir — bir double-fetch.
Handler'ın güvendiği field, artık kullandığı field değildir.
Walkthrough¶
NCC Group'un Intel SPI flash SMM handler'ı (CVE-2022-21198, INTEL-SA-00688) analizi kanonik public örnektir:
- Handler
SmmIsBufferOutsideSmmValid'i çağırır ve buffer'ı internal birSmmSpiFunctionHeader'a kopyalar. Buraya kadar doğru. - Ama per-subcommand range check'leri (örn.
SPI_FUNCTION_FLASH_READ), field'ları internal kopya yerine external aliasExternalSmmSpiFunctionHeader->...üzerinden doğrular. - Yarışan bir ajan, check'ten sonra ama SMM onları dereference etmeden önce
ExternalSmmSpiFunctionHeader->Buffer/->ByteCount'u yeniden yazar. - Sonuç: SMM out-of-range pointer'lar üzerinde çalışır → SMRAM corruption / ring -2 exec.
# Conceptual double-fetch in the handler (illustrative):
if (valid(External->ByteCount)) { // time-of-check (external pointer!)
...
do_io(External->Buffer, External->ByteCount); // time-of-use, re-fetched
} // attacker mutated it in between
Sekiz subcommand etkilendi (FLASH_READ/WRITE/READ_SFDP/READ_JEDEC_ID/ WRITE_STATUS/READ_STATUS/GET_REGION_ADDRESS/READ_*_SOFTSTRAP).
Warning
Savunma/eğitsel amaçlı; yalnızca public NCC writeup'ından ve CERT notundan
kavramsal olarak yeniden üretin. Aynı yarışın DMA-driven varyantı için
toctou-smm-via-dma.md'ye bakın.
Detection¶
- SMI handler'ları, ilk validation/copy'den sonra external CommBuffer pointer'ını kullanan herhangi bir field erişimi (bir double-fetch) için denetleyin.
- CHIPSEC SMM fuzzing'i ve differential check'leri tutarsız davranışı ortaya çıkarabilir.
Mitigation¶
- Doğruladıktan sonra tüm CommBuffer'ı SMRAM'e kopyalayın ve tüm check ve use'ları local kopyaya karşı yapın — external pointer'a bir daha asla dokunmayın.
- Satıcı SMM firmware güncellemelerini uygulayın (INTEL-SA-00688 vb.).