Skip to content

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:

  1. Handler SmmIsBufferOutsideSmmValid'i çağırır ve buffer'ı internal bir SmmSpiFunctionHeader'a kopyalar. Buraya kadar doğru.
  2. Ama per-subcommand range check'leri (örn. SPI_FUNCTION_FLASH_READ), field'ları internal kopya yerine external alias ExternalSmmSpiFunctionHeader->... üzerinden doğrular.
  3. Yarışan bir ajan, check'ten sonra ama SMM onları dereference etmeden önce ExternalSmmSpiFunctionHeader->Buffer / ->ByteCount'u yeniden yazar.
  4. 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.).

References