Skip to content

Branch Target Identification (BTI)

Guarded page'lerdeki indirect branch'leri yalnızca bir BTI "landing pad"e inmeye zorlayan ve jump-oriented programming'i kıran ARMv8.5-A control-flow integrity.

Mechanism

Note

JOP (jump-oriented programming), fonksiyonların ortasına jump etmek için indirect branch'leri (BR, BLR) suistimal ederek gadget'lar zincirler. BTI şu invariant'ı enforce eder: guarded bir page'e yapılan bir indirect branch açık bir landing-pad instruction'ına inmelidir — aksi halde CPU fault verir. Bu, legal indirect-branch target setini küçük, compiler tarafından yerleştirilmiş bir sete daraltır.

ARMv8.5-A, 2-bit'lik bir processor-state field olan PSTATE.BTYPE'ı (bit'ler PSTATE[11:10]) ekler. Bir indirect branch execute ettiğinde, hardware BTYPE'ı branch türüne göre ayarlar. Page'ler translation table'da bir Guarded Page (GP) attribute taşıyabilir (Linux'ta stage-1 descriptor'da PTE_GP = 1 << 50). Guarded bir bölge içinde, PSTATE.BTYPE != 0b00 iken, uyumlu bir landing pad dışında her instruction bir Branch Target Exception üretir. Arm A64 ISA'nın Branch Target Exception üretmediğini belgelediği instruction seti BRK, BTI, HLT, PACIASP ve PACIBSP'dir; fakat legitimate forward-edge landing pad rolünü yalnızca BTI (variant'ları c, j, jc) ile call-tarafında PACIASP / PACIBSP üstlenir — BRK ve HLT bu listede yer alır çünkü kendi debug / halt exception'larını üretirler, code-flow landing pad'i değildirler. Guarded bir bölge dışındaki (veya BTYPE == 0b00 olan) bir BTI instruction'ı NOP olarak execute eder.

BTI instruction'ı, hangi branch türlerini kabul ettiğini kontrol eden, BTYPE ile eşleştirilen bir target class operand'ı alır:

BTYPE anlamı izin verilen landing instruction'ları
0b00 branch değil herhangi bir instruction
0b01 jc BTI jc, BTI j, BTI c, PACIxSP
0b10 c (call) BTI jc, BTI c, PACIxSP
0b11 j (jump) BTI jc, BTI j

Uyumlu bir landing pad check'i temizler ve execution'ın devam etmesine izin verir; başka her şey Branch Target Exception'ı tetikler. Pointer Authentication ile birleştiğinde, PACIASP aynı zamanda bir call landing pad görevi görür, dolayısıyla PAC+BTI birlikte return ve forward edge'leri kapsar.

Walkthrough

Branch protection ile derle ve üretilen landing pad'leri incele:

$ aarch64-linux-gnu-gcc -mbranch-protection=bti -c foo.c -o foo.o
$ aarch64-linux-gnu-objdump -d foo.o | head
0000000000000000 <foo>:
   0:   d503245f        bti     c          # call landing pad at function entry
   4:   ...

-mbranch-protection=standard, bti artı PAC return-address signing'i enable eder. Toolchain ayrıca bir ELF note (GNU_PROPERTY_AARCH64_FEATURE_1_BTI) üretir ki loader object'in BTI-clean olduğunu bilsin:

$ readelf -n foo.o | grep -i feature
      Properties: AArch64 feature: BTI

Linux'ta guarded page'ler map zamanında talep edilir. Kernel, bir page PROT_BTI ile map edildiğinde GP attribute'unu ayarlar; dynamic linker bunu BTI-marked ELF object'lerin executable segment'lerine uygular:

mmap(addr, len, PROT_READ | PROT_EXEC | PROT_BTI, flags, fd, off);

Bir indirect branch guarded bir page'de bir non-landing-pad instruction'ına indiğinde, kernel Branch Target Exception'ı (Linux EC ESR_ELx_EC_BTI = 0x0D) si_code == ILL_BTCFI ile SIGILL olarak teslim eder:

Program terminated with signal SIGILL, Illegal instruction.
# si_code = ILL_BTCFI  (BTYPE mismatch on indirect branch)

Warning

BTI yalnızca guarded page'lere yapılan, valid landing pad'leri olan indirect branch'leri kısıtlar. PROT_BTI taşımayan bir page, tesadüfen legitimate bir BTI c entry'si olan bir JOP target'ı veya bir direct branch üzerinden erişilebilen code kısıtlanmaz. BTI, JOP'un maliyetini yükseltir; tam bir CFI çözümü değildir ve Pointer Authentication ile eşleştiğinde en güçlüdür.

Detection

  • Bir binary'nin ve library'lerinin gerçekten landing pad'lerle build edildiğini doğrulamak için ELF note'larını (readelf -n) AArch64 BTI feature bit'i için incele.
  • CPU'nun BTI advertise ettiğini doğrula: grep -o bti /proc/cpuinfo (HWCAP2_BTI).
  • ILL_BTCFI ile bir SIGILL, bir indirect branch'in illegal bir target'a isabet ettiğini gösterir — runtime'da denenmiş bir JOP-tarzı hijack'in güçlü bir sinyali.

References