Skip to content

Intel Memory Protection Extensions (historical)

Kullanımdan kaldırılmış Skylake dönemi hardware bounds checking'i: dört BND0-BND3 register'ı artı pointer dereference'lerinin etrafına yerleştirilen bndcl/bndcu kontrolleri; zayıf performans ve benimsenme sonrası GCC 9'dan, Linux kernel'inden (5.6) ve glibc'den (2.35) kaldırıldı.

Mechanism

Neden çalışır

MPX, spatial memory safety'ye — out-of-bounds read'ler ve write'lar — her pointer'a açık lower/upper bound'lar ilişkilendirerek ve her dereference'i hardware'de bunlara karşı kontrol ederek saldırdı; böylece bir buffer overflow komşu belleği bozmak yerine fault verir.

  • Dört 128-bit bounds register'ı BND0-BND3'ün her biri bir çift 64-bit değer tutar: pointer'ın içinde kalması gereken nesnenin bir lower bound'u (LB) ve bir upper bound'u (UB).
  • Compiler kodu instrumente eder, böylece bir pointer üzerinden her load veya store'dan önce bir bounds check emit eder: bndcl (lower bound'u kontrol et) ve bndcu/bndcn (upper bound'u kontrol et), bir GPR'daki pointer'ı bir BND register'ındaki bound'larla karşılaştırır; bir ihlal bir #BR bound-range-exceeded exception'ı doğurur. bndmk yeni bound'lar yaratır, bndmov bound'ları register'dan register'a veya belleğe taşır.
  • Yalnızca dört BND register'ı ama sınırsız sayıda canlı pointer olduğundan, bound'lar pointer'ın kendi konumuyla adreslenen bir iki seviyeli Bounds Directory / Bounds Table yapısı aracılığıyla belleğe spill olur: bndstx bir pointer'ın bound'larını table'a depolar ve bndldx onları geri yükler, böylece bound'lar bir pointer'ı bellek boyunca "takip eder".
  • Configuration ve status özel register'larda durur: BNDCFGU (user-mode config) / IA32_BNDCFGS (supervisor) feature'ı etkinleştirir ve bound directory base'ini tutar, BNDSTATUS ise bir #BR fault'unun nedenini kaydeder. Legacy prefix encoding'i, BND instruction'larının MPX'siz CPU'larda NOP olarak decode edilmesi anlamına gelir, dolayısıyla tek bir binary her ikisinde de çalışabilir.

Invariant: her instrumente edilmiş dereference, pointer'la birlikte gezinen bound'lara karşı kontrol edilir. Pratikte bu invariant pahalı ve eksikti — MPX'in şimdi tarih olmasının nedeni budur.

Walkthrough

1. MPX instrumentation'ı ile derle (onu destekleyecek kadar eski bir toolchain'de). GCC < 9 ve ICC -fcheck-pointer-bounds -mmpx'i kabul ediyordu:

$ gcc -fcheck-pointer-bounds -mmpx -o demo demo.c    # GCC <= 8 only

2. Emit edilen kontrolleri incele. Bir pointer store'unun etrafında compiler erişimi bounds instruction'larıyla parantezler:

bndmk   (%rdi,%rsi,1), %bnd0      ; make bounds [rdi .. rdi+rsi] for buffer
bndcl   (%rax), %bnd0             ; check rax >= lower bound
bndcu   7(%rax), %bnd0            ; check rax+7 <= upper bound  (#BR on violation)
mov     %rcx, (%rax)              ; the now-checked store

Not: bndcl/bndcu'daki (%rax) bir memory load değildir — MPX bu operand'ın effective address'ini lea gibi hesaplar (bellek okunmaz) ve bu adres değerini bound'a karşı kontrol eder; dolayısıyla (%rax) adres rax'i, 7(%rax) ise rax+7'yi denetler.

3. Register'lardan daha uzun yaşayan bound'lar table aracılığıyla spill olur:

bndstx  %bnd0, (%rbx,%rax,1)      ; store bounds for pointer at [rbx+rax]
; ... later ...
bndldx  (%rbx,%rax,1), %bnd0      ; reload them before dereference

4. Modern bir stack'te gittiğini doğrula. Güncel compiler'lar flag'leri reddeder — feature kaldırıldı:

$ gcc -fcheck-pointer-bounds -mmpx -c demo.c
cc1: error: '-fcheck-pointer-bounds' is not supported with MPX disabled/removed

MPX neden terk edildi

MPX kötü ölçüm verdi ve az şeyi kapsadı: çalışmalar en kötü durumda ~4x'e kadar yavaşlama (~%50 ortalama) bildirdi, yalnızca spatial safety'yi korudu (use-after-free / temporal koruma yok), bounds-table güncellemelerinde thread-safety tehlikeleri vardı ve diğer extension'larla çakışıyordu. Kaldırma hızla geldi: GCC 9.1 onu düşürdü, Linux kernel MPX'i 5.6'da kaldırdı, glibc 2.35 MPX desteğini kaldırdı ve Intel MPX'i deprecate etti, sonraki CPU'larda yokluğunu bıraktı. Yerini bunun yerine software bounds checker'lar (AddressSanitizer) ve ARM MTE / pointer şemaları doldurdu.

References