Skip to content

Clang CFI (forward-edge, LTO)

LLVM'nin -fsanitize=cfi'si: indirect call'ları ve C++ cast'lerini LTO bit-set / jump-table check'leriyle beklenen static type'larına karşı doğrulayan, compile-time bir forward-edge CFI.

Mechanism

Note

Clang CFI bir forward-edge savunmasıdır. indirect call'ları, virtual/non-virtual call'ları ve pointer cast'lerini instrument eder, böylece runtime'da hedefin gerçek dynamic type'ı o site'ta izin verilen type kümesine karşı kontrol edilir. İzin verilen hedef kümeleri kompakt bit-set'lere ve jump-table range check'lerine derlenir — şemanın link-time-optimization'a bağımlı olmasının sebebi de budur: belirli bir type'a ait her legal vtable veya fonksiyonu numaralandırmak için -flto'nun verdiği whole-program görünümü gerekir. Şema bağımsız alt şemalara ayrılır: cfi-vcall, cfi-nvcall, cfi-derived-cast, cfi-unrelated-cast, cfi-icall, cfi-mfcall, artı şemsiye cfi.

Varsayılan olarak bir ihlal anında trap eder (mesajsız bir illegal-instruction / ud2 abort'u); diagnostic'ler ve recovery opt-in'dir.

Walkthrough

LTO ve hidden visibility ile derle + link'le:

clang -flto -fvisibility=hidden -fsanitize=cfi -o app app.c

-fvisibility=hidden, explicit visibility'si olmayan class'ların conservative biçimde dışlanmak yerine yine de kontrol edilmesi için gereklidir. LTO yeteneğine sahip bir linker (lld/gold) gerekir. Tek bir alt şemayı örneğin -fsanitize=cfi-icall ile etkinleştir.

İhlalde varsayılan: sessiz bir trap (x86'da ud2). Bunun yerine bir diagnostic almak için -fno-sanitize-trap=cfi ekle:

Runtime CFI diagnostic
bad-cast.cpp:109:7: runtime error: control flow integrity check for type 'B'
failed during base-to-derived cast (vtable address 0x000000425a50)

Cross-shared-object enforcement: -fsanitize-cfi-cross-dso ekle; bu, type check'lerini tek bir LTO unit'ine hapsetmek yerine DSO sınırları boyunca emit eder.

Mitigation

CFI'nin type equivalence sınıfları coarse'tur — eşleşen type'a ait herhangi bir fonksiyon/vtable legal bir hedeftir, dolayısıyla bir saldırgan kontrolü farklı-ama-type-uyumlu bir hedefe yönlendirebilir. Akademik bypass'lar, return-address integrity olmadan precise CFI'nin bile yetersiz olduğunu gösterir: bkz. Control Jujutsu (gerçek pointer analysis'in imprecision'ı) ve Control-Flow Bending (valid-ama-infeasible CFG trace'leri). Kernel tarafında bu, FineIBT ve kernel CFI ile sertleştirilir.

References