[Scenario 05] 제어 흐름 하이재킹 & Clang kCFI / 하드웨어 IBT/BTI 방어¶
🎯 발표 핵심 요약 (Executive Summary)
- 실제 공격 사례: 리눅스 커널 cgroup 및 파일시스템 서브시스템 타입 혼동(Type Confusion)을 통한 함수 포인터 변조 (CVE-2021-4154)
- 위협 벡터: 디바이스 드라이버 및 서브시스템의 함수 포인터 테이블(
ops->dispatch_fn) 메모리를 오염시켜, 합법적 기구학 연산 루틴 대신 악의적인 관절 과부하 루틴 또는 임의 커널 코드로 간접 분기(Indirect Call) 유도 - 사이버-물리 피해: 2족 보행 관절 구동 모터 지령 각속도가 정상 1.8 rad/s에서 48.5 rad/s(27배 폭증)로 급변하여 하모닉 드라이브 감속기 기어 치절 전단 파괴(Gear Shear) 및 브러시리스 서보 모터 고정자 권선 소손 발생
- 1차 소프트웨어 방어선: 컴파일러 기반 정밀 전방향 제어 흐름 무결성
CONFIG_CFI_CLANG=y(Clang kCFI) (32비트 프리앰블 타입 해시 검증) - 2차 하드웨어 협력 방어선: CPU 명령어 추적기 Intel CET IBT (
CONFIG_X86_KERNEL_IBT) 및 ARM64 BTI (CONFIG_ARM64_BTI) (랜딩패드ENDBR64/BTI c강제)
1. 실제 커널 침해 사례 분석: CVE-2021-4154와 휴머노이드 관절 제어기 파괴¶
C 언어로 작성된 리눅스 커널은 객체 지향적 다형성을 구현하기 위해 구조체 내부의 함수 포인터(Function Pointer Tables / Ops)를 광범위하게 활용함:
[로봇 사용자 공간 (Locomotion Planner / C2: Ring 3)]
│
│ (1) fs/cgroup 취약점 트리거 (Type Confusion 유발)
▼
[커널 힙/데이터 영역 (Actuator Driver Ops Table)]
┌───────────────────────────────────────┐
│ struct joint_controller_ops │
├───────────────────────────────────────┤
│ name : "Knee_Pitch_Controller" │
│ dispatch_fn : 0x578896262690 (변조됨) │ <── [CVE-2021-4154로 조작]
└───────────────────────────────────────┘
│
│ (2) (*ops->dispatch_fn)(actuator, target, vel) 간접 호출
▼
[변조된 악성 페이로드: malicious_actuator_overload()]
- Target Angle : 3.14159 rad (급격한 관절 반전)
- Commanded Velocity : 48.5 rad/s (정상 허용치 1.8 rad/s 대비 27배 폭주)
│
▼
[💥 사이버-물리 파괴 전이: 감속기 치절 전단 파괴 & 서보 모터 소손]
1.1 침해 경로 및 근본 원인 (Root Cause)¶
- CVE-2021-4154 (커널 타입 혼동 및 포인터 오염):
- 리눅스 cgroup 및 fs 서브시스템에서 객체 타입 캐스팅 검증 미비로 인해 서로 다른 구조체 오프셋이 중첩 매핑되는 타입 혼동(Type Confusion) 결함 발생함.
- 공격자는 이 결함을 악용하여 커널 드라이버의 간접 호출 테이블(
ops->dispatch_fn) 위치에 공격자가 지정한 임의 주소를 덮어씀.
- 간접 호출 취약점 (Indirect Branch Vulnerability):
- 전방향 제어 흐름 무결성(Forward-Edge CFI)이 적용되지 않은 기본 커널(
CONFIG_CFI=n)에서는 CPU가call *%rax명령어를 수행할 때 대상 주소가 본래 의도된 프로토타입의 함수인지 전혀 확인하지 않음. - 함수 포인터가 가리키는 메모리에 실행 권한(
+X)만 부여되어 있다면, 공격자가 지정한 악성 루틴이나 임의 커널 함수로 즉시 분기하여 최고 권한(Ring 0) 상태에서 파괴적 행위를 자행함.
- 전방향 제어 흐름 무결성(Forward-Edge CFI)이 적용되지 않은 기본 커널(
1.2 사이버-물리적 재난 분석 (Cyber-Physical Hazards)¶
관절 제어 디스패처의 제어 흐름 탈취는 로봇의 물리 기구부에 치명적인 비가역적 파괴를 초래함:
- 🔴 관절 각속도 27배 한계 초과 폭주 (Mechanical Overspeed):
- 안전 최대 각속도가 1.8 rad/s인 무릎 피치 축에 48.5 rad/s의 초고속 지령이 인가되어 관절 가동 범위를 한순간에 이탈함.
- 🔴 하모닉 드라이브 감속기 치절 전단 파괴 (Gear Teeth Shear):
- 감속비 100:1의 정밀 탄성파 감속기 톱니가 급격한 충격 토크를 견디지 못하고 기계적으로 전단(Shear) 파괴되어 유격 발생 및 관절 고정 불능 상태 초래함.
- 🔴 브러시리스 서보 모터 권선 과전류 소손 (Motor Stator Burnout):
- 모터 인버터에 순간 최대 정격 전류의 400% 이상이 인가되어 고정자(Stator) 코일 피복이 용융되고 영구 단락 화재 발생함.
2. 간접 분기 탈취 및 kCFI / IBT 방어 메커니즘¶
제어 흐름 무결성(CFI)은 소프트웨어의 실행 흐름을 컴파일 타임에 생성된 정적 제어 흐름 그래프(CFG) 내로 강제 제한하는 보안 기법임.
2.1 Forward-Edge vs Backward-Edge CFI 분류¶
제어 흐름 공격은 분기 지점의 성격에 따라 2가지로 양분됨:
[제어 흐름 분기점]
├── 전방향 분기 (Forward-Edge) : 간접 호출(call *%rax), 간접 점프(jmp *%rax) ──> [Clang kCFI / Intel IBT / ARM64 BTI]
└── 후방향 분기 (Backward-Edge) : 함수 반환(ret) 명령어 (스택 리턴 주소) ──> [Shadow Call Stack / Intel SHSTK]
- 전방향 분기 보호 (Forward-Edge CFI):
- 함수 포인터를 통한 동적 분기 지점을 감시함.
- Clang kCFI는 호출될 함수의 프로토타입(매개변수 및 반환 타입)이 호출 지점의 기대 규격과 정확히 일치하는지 검증함.
- 후방향 분기 보호 (Backward-Edge CFI):
- 함수 종료 시 복귀 주소를 변조하는 ROP(Return-Oriented Programming)를 방어함.
- 하드웨어 섀도 스택(SHSTK)이나 전용 레지스터 스택(SCS)을 통해 리턴 주소의 무결성을 보장함.
2.2 Clang kCFI 프리앰블 타입 해싱 아키텍처¶
기존의 Clang CFI는 런타임에 전역 점프 테이블(Jump Table)을 참조하여 커널 LTO(Link-Time Optimization)가 필수적이었으며, 동적 커널 모듈 적재 시 호환성 문제가 존재했음. 리눅스 6.1부터 도입된 kCFI (Kernel Control Flow Integrity)는 함수 진입점 바로 앞(-4바이트)에 독립적인 32비트 타입 해시를 삽입하는 프리앰블(Preamble) 방식을 채택함:
[호출 지점: Caller] [대상 함수: Callee (safe_joint_kinematics)]
movl -4(%rax), %r10d ──(타입 해시 로드)──> -4B: [ 0x5A8E3F21 ] (32비트 kCFI 타입 해시)
cmpl $0x5A8E3F21, %r10d +0B: [ endbr64 ] (하드웨어 랜딩패드)
jne .Ltrap_abort +4B: [ push %rbp ] (실제 함수 본문)
call *%rax ...
- 공격자가 임의의 악성 함수(
malicious_actuator_overload)나 kCFI 서명이 누락된 쉘코드로 점프를 시도할 경우, 프리앰블의 타입 해시가 불일치(0x00000000 != 0x5A8E3F21)하여 즉각ud2트랩 발동함.
3. 대화형 인터랙티브 아키텍처 다이어그램 (Interactive Diagrams)¶
아래 4개 단계별 다이어그램 및 통합 아키텍처 다이어그램을 통해 간접 분기 수행, 공격자의 함수 포인터 변조, kCFI/IBT 하드웨어 트랩, 하드웨어 페일세이프 E-Stop 전 과정을 시각적으로 확인 가능함.
3.1 [Phase 1] 정상 간접 함수 분기 및 kCFI 타입 시그니처 일치 (Nominal Flow)¶
3.2 [Phase 2] 함수 포인터 변조 & 제어 흐름 하이재킹 공격 (Attack Detonation)¶
3.3 [Phase 3] Clang kCFI 타입 해시 불일치 트랩 & 하드웨어 IBT 차단 (Hardened Trap)¶
3.4 [Phase 4] 하드웨어 페일세이프 E-Stop 및 관절 긴급 제동 (Deterministic Safe State)¶
3.5 [통합 아키텍처] 제어 흐름 무결성(kCFI & IBT/BTI) 방어 아키텍처 타임라인 (Comprehensive Flow)¶
4. 방어 기법 심층 분석 및 하드닝 매트릭스 (Defense Matrix)¶
리눅스 커널은 전방향 및 후방향 제어 흐름 왜곡을 원천 봉쇄하기 위해 컴파일러와 하드웨어 CPU 기능을 결합함:
| 방어 기술 | 커널 Kconfig 설정 | 보호 영역 및 검증 방식 | 성능 오버헤드 |
|---|---|---|---|
| Clang kCFI | CONFIG_CFI_CLANG=y |
전방향 간접 호출 (call *%reg) 프리앰블 32비트 타입 해시 검증 |
< 1.0% (극저부하, 모듈 완전 지원) |
| x86 Indirect Branch Tracking (IBT) | CONFIG_X86_KERNEL_IBT=y |
전방향 간접 분기 타깃에 하드웨어 ENDBR64 랜딩패드 강제 (#CP 예외) |
0% (Intel 11세대+ 하드웨어 지원) |
| ARM64 Branch Target Identification (BTI) | CONFIG_ARM64_BTI=y |
ARMv8.5+ 간접 분기 대상에 BTI c 명령어 필수 배치 검증 |
0% (ARM64 하드웨어 지원) |
| Shadow Call Stack (SCS) | CONFIG_SHADOW_CALL_STACK=y |
후방향 함수 반환 주소(ret)를 별도 x18 레지스터 섀도 스택에 이중 보관 |
< 2.0% (ROP 100% 방어) |
4.1 [소프트웨어 방어선] Clang kCFI (CONFIG_CFI_CLANG)¶
-
⚙️ 작동 원리 (Mechanism)
- 컴파일 타임 타입 해시 산출:
- Clang 컴파일러가 각 C 함수 프로토타입의 맹글링된 문자열로부터 32비트 고유 정수 해시를 산출함.
- 모든 함수의 시작 위치 바로 앞(-4바이트)에 해당 해시값을 상수로 삽입함.
- 인라인 검증 코드 삽입:
- 함수 포인터를 통한 간접 호출 직전 대상 주소의
-4B위치에서 해시를 읽어 기대 해시와 대조하는 어셈블리 명령어를 자동 삽입함. - 불일치 시
ud2명령어를 실행하여 커널#UD예외를 격발함.
- 함수 포인터를 통한 간접 호출 직전 대상 주소의
- 컴파일 타임 타입 해시 산출:
-
🛡️ 방어 효과 (Defense Impact)
- 타입 불일치 간접 호출 원천 봉쇄:
- 공격자가 함수 포인터를 임의의 커널 함수(
commit_creds등)나 미인가 코드로 변조하더라도 시그니처가 다르면 0% 실행 차단됨.
- 공격자가 함수 포인터를 임의의 커널 함수(
- LTO 불필요 및 완벽한 모듈 호환성:
- 기존 Fine-grained CFI와 달리 커널 LTO 없이도 작동하며, 외부 로드 가능 커널 모듈(LKM)과 완벽히 상호 호환됨.
- 타입 불일치 간접 호출 원천 봉쇄:
4.2 [하드웨어 방어선] x86 IBT & ARM64 BTI¶
-
⚙️ 작동 원리 (Mechanism)
- 하드웨어 상태 머신 추적:
- 간접 분기(
jmp *%rax,call *%rax)가 발생하는 즉시 CPU 코어가WAIT_FOR_ENDBR상태로 전이됨.
- 간접 분기(
- 랜딩패드 강제 검증:
- 다음 페치되는 첫 번째 명령어가 x86의
ENDBR64또는 ARM64의BTI c가 아닐 경우, CPU 하드웨어가 즉각#CP(Control Protection) 또는 BTI 폴트를 격발하여 명령 실행을 정지함.
- 다음 페치되는 첫 번째 명령어가 x86의
- 하드웨어 상태 머신 추적:
-
🛡️ 방어 효과 (Defense Impact)
- 함수 내부 임의 위치 가젯(ROP/JOP) 점프 차단:
- 정상 함수의 진입점이 아닌 함수 중간의 가젯(Gadget)으로 뛰어드는 분기 시도를 하드웨어 0클록 수준에서 즉각 차단함.
- 함수 내부 임의 위치 가젯(ROP/JOP) 점프 차단:
5. 실습 환경 및 공격 시뮬레이션 데모 (kcfi_demo.c)¶
본 실습에서는 CVE-2021-4154 타입 혼동 취약점을 모사한 C 언어 시뮬레이터(kcfi_demo.c)를 빌드하고, 취약 모드와 하드닝 모드의 동작 차이를 실측 검증함.
5.1 시뮬레이터 핵심 아키텍처 (kcfi_demo.c)¶
- 실습 소스 코드:
kcfi_demo.c(로컬 원본) | GitHub 소스 코드 저장소 :octicons-mark-github-16: - 메모리 구조: 로봇 무릎 피치 축 액추에이터 제어기(
robot_joint_actuator_t)와 함수 포인터 디스패치 테이블(joint_controller_ops_t) 모델링. - 방어 로직 구현: Clang kCFI 프리앰블 타입 해시(
0x5A8E3F21) 검사 및 하드웨어 랜딩패드(ENDBR64) 유효성 검증 루틴 구현.
/* labs/scenarios/05-kcfi/kcfi_demo.c 간접 분기 검증 함수 */
static bool verify_indirect_call(joint_controller_ops_t *ops, uint32_t expected_type, bool kcfi_enabled, bool ibt_enabled) {
if (!kcfi_enabled && !ibt_enabled) {
return true; /* CFI 미적용 취약 모드 */
}
/* 1. 하드웨어 IBT / BTI 랜딩패드 검증 */
if (ibt_enabled && (!ops->preamble || ops->preamble->landing_pad != LANDING_PAD_ENDBR64)) {
printf("[HARDWARE FAULT: #CP / BTI] Indirect branch target missing valid landing pad!\n");
return false;
}
/* 2. Clang kCFI 소프트웨어 프리앰블 타입 해시 검증 */
if (kcfi_enabled && (!ops->preamble || ops->preamble->kcfi_typeid != expected_type)) {
printf("[KCFI TRAP: #UD / PANIC] Indirect call target type mismatch! Expected: 0x%08X\n", expected_type);
return false;
}
return true;
}
5.2 공격 실행 및 기구부 파괴 경고 로그 (Attack Execution Logs)¶
CFI 방어가 비활성화된 취약 모드(CONFIG_CFI=n)에서 간접 분기 조작을 감행했을 때의 실측 실행 로그는 다음과 같음:
런타임 경고 텔레메트리 출력 로그:
======================================================================
🤖 Humanoid Robot Control Flow Hijacking & Clang kCFI Lab (CVE-2021-4154)
======================================================================
[MODE 2: TYPE CONFUSION & INDIRECT CALL HIJACK WITHOUT CFI (CONFIG_CFI=n)]
[*] Simulating CVE-2021-4154: Kernel Type Confusion corrupting function pointer in ops struct...
[!] Attacker overwrites ops->dispatch_fn with hostile payload: 0x578896262690
[!] Baseline kernel executes: (*ops->dispatch_fn)(actuator, target, vel) without validation...
======================================================================
[💥 CRITICAL EXPLOIT DETONATION] Control Flow Hijacking Succeeded!
======================================================================
[*] Forward-edge indirect branch hijacked to untrusted memory!
[*] Current Context: Ring 0 Kernel Execution (Arbitrary Function Detonated)
--- [PHASE 1: CYBER-PHYSICAL HAZARDS & MECHANICAL DAMAGE] ---
[🔴 PHYSICAL HAZARD] Commanded Velocity: 1.8 rad/s -> 48.5 rad/s (LETHAL OVERSPEED)
[🔴 PHYSICAL HAZARD] Joint Harmonic Drive: Mechanical Gear Teeth Sheared!
[🔴 PHYSICAL HAZARD] Stator Coil Overcurrent: Brushless Servo Motor Burnout!
5.3 하드닝 모드 검증 및 커널 트랩 로그 (Hardened Defense & Safe E-Stop Logs)¶
CONFIG_CFI_CLANG=y 및 CONFIG_X86_KERNEL_IBT=y 환경에서 동일 공격을 감행했을 때의 실측 로그:
런타임 방어 및 페일세이프 텔레메트리 출력 로그:
======================================================================
🤖 Humanoid Robot Control Flow Hijacking & Clang kCFI Lab (CVE-2021-4154)
======================================================================
[MODE 3: HIJACK ATTEMPT INTERCEPTED BY CLANG KCFI & HARDWARE IBT/BTI]
[*] Initializing Hardened Kernel Environment (CONFIG_CFI_CLANG=y, CONFIG_X86_KERNEL_IBT=y)...
[*] Kernel initiates indirect branch to ops->dispatch_fn (0x619fe45ae690)...
[*] Clang kCFI and CPU Instruction Tracker inspect branch target...
[HARDWARE FAULT: #CP / BTI] Indirect branch target missing valid landing pad (ENDBR64/BTI)!
======================================================================
[🛡️ CONTROL FLOW VIOLATION DETECTED] Clang kCFI Type Hash Abort!
======================================================================
[!] CFI INTERCEPTION FORENSICS:
Expected Type Hash = 0x5A8E3F21 (void (*)(actuator_t*, float, float))
Found Type Hash = 0x00000000 (Untagged / Mismatched Function Signature)
Hardware LandingPad = 0x90909090 (Invalid / Missing ENDBR64)
[!] Kernel Action: Immediate #UD Trap -> Kernel Panic / Oops triggered.
[!] Indirect Call Executed: 0%. Hostile payload neutralized.
[FAIL-SAFE ACTIVE] Hardware Safety Relay engaged: Motor Bus Power cut to 0.0V!
[FAIL-SAFE ACTIVE] Actuator parking brake clamped. Robotic limbs immobilized safely!
5.4 아키텍처 핵심 분석: Rooting (UID 0 / Ring 3) vs Kernel Space Control (Ring 0)의 결정적 차이¶
제어 흐름 장악(Control Flow Hijack)은 단순 유저 공간 루트 권한 획득(Rooting)과 시스템 장악 차원에서 본질적인 격리 장벽 차이를 가짐:
[보안 평가 축] [루팅 권한 (UID 0 / Ring 3)] [제어 흐름 장악 (Ring 0 kCFI Hijack)]
명령어 실행 레벨 CPU Ring 3 (유저 공간 모드) CPU Ring 0 (커널 슈퍼바이저 모드)
간접 분기 대상 자산 유저 프로세스 주소 공간에 국한됨 전체 물리 메모리 및 커널 내부 미공개 함수
하드웨어 MMIO 버스 제어 /dev 노드 통신 API 제약 준수 서보 모터 CAN/EtherCAT 컨트롤러 직통 변조
LSM 보안 검증 무력화 SELinux MAC 정책에 의해 차단 가능 security_hook_heads 자체를 우회 분기
워치독 인터록 해제 하드웨어 인터록 우회 불가능 타이머 인터럽트 핸들러 무력화 가능
- 루팅 권한(UID 0)의 격리 한계:
- 루트 사용자는 시스템 파일을 조작할 수 있으나, CPU는 여전히 Ring 3에서 동작하므로 커널 내부의 정적 함수 포인터나 MMU 레지스터를 직접 조작할 수 없음.
- 커널 제어 흐름 장악(Ring 0 kCFI Hijack)의 전면 파괴력:
- 공격자가 커널 모드 간접 호출을 탈취하는 데 성공하면, CPU가 Ring 0 권한으로 공격자가 원하는 커널 내부 코드를 무제한 실행함.
- 하드웨어 세이프티 가드 해제, 모터 구동 버스 오버볼티지 인가, 디스크 펌웨어 변조 등 되돌릴 수 없는 물리적 재해를 유발할 수 있으므로 kCFI와 IBT를 통한 1차 방어가 절대적으로 필수적임.
6. 엔지니어링 심층 분석 (Engineering Deep Dive)¶
6.1 Clang kCFI 어셈블리 생성 및 타입 해시 인라인 검증¶
Clang이 -fsanitize=kcfi 옵션으로 컴파일할 때 간접 호출 지점에 삽입하는 실제 x86-64 어셈블리:
# 호출 대상 함수: safe_joint_kinematics
.section .text
.p2align 4
.long 0x5a8e3f21 # __kcfi_typeid_kinematics (-4B 오프셋)
safe_joint_kinematics:
endbr64 # x86 IBT Landing Pad (+0B 오프셋)
pushq %rbp
movq %rsp, %rbp
...
# 간접 호출 지점: caller (actuator.c)
movq ops(%rip), %rax
movq 16(%rax), %r11 # r11 = ops->dispatch_fn 주소
movl -4(%r11), %r10d # r10d = 대상 함수의 프리앰블 해시 로드
cmpl $0x5a8e3f21, %r10d # 기대 프로토타입 해시와 대조
je .Lcall_valid
ud2 # 불일치 시 하드웨어 #UD 트랩 발생!
.Lcall_valid:
callq *%r11
- 타입 해시 유일성: 매개변수 타입(
uint32_t,float,float)과 반환형(void)의 맹글링 문자열을 암호학적으로 해싱하여 32비트 정수로 축약하므로 서로 다른 시그니처 간 충돌 확률이 \(2^{-32}\)로 극히 낮음.
6.2 하드웨어 IBT 상태 머신 및 #CP 예외 벡터¶
인텔 간접 분기 추적기(IBT)의 하드웨어 마이크로아키텍처 동작 원리:
[간접 분기 전] [간접 점프 발생] [다음 명령어 페치]
IDLE 상태 ───> WAIT_FOR_ENDBR 상태 ───> 첫 명령어 != ENDBR64 ?
(간접 점프 완료 직후) │
├── YES : #CP 예외 발생 (Vector 21)
└── NO : IDLE 복귀 (정상 실행)
- 예외 발생 시 동작: CPU가 인터럽트 디스크립터 테이블(IDT)의 벡터 21번(
#CP) 핸들러를 즉각 호출하여 공격 코드가 단 1개의 인스트럭션도 실행하지 못하도록 하드웨어 파이프라인을 동결함.
6.3 ARM64 BTI & PAC 하드웨어 협력¶
ARM64 아키텍처는 두 가지 하드웨어 기술을 결합하여 완벽한 CFI를 달성함:
- BTI (Branch Target Identification):
- x86 IBT와 동일하게 간접 분기 타깃에
BTI c명령어가 없으면 즉각Branch Target Exception을 발생시킴. - PAC (Pointer Authentication Code):
- 함수 포인터를 저장할 때 상위 16비트에 64비트 비밀키와 컨텍스트 기반 암호화 서명(
PACIA)을 주입함. - 호출 시
AUTIA명령어로 서명을 검증하며, 메모리가 변조되었을 경우 유효하지 않은 주소로 붕괴시켜 즉각#PF크래시를 유도함.
6.4 로봇 사이버-물리 페일세이프 아키텍처¶
제어 흐름 이상 감지 시 물리적 파손을 차단하는 2선 방어 체계:
- 하드웨어 안전 워치독 인터럽트(Hardware Watchdog):
- kCFI
#UD트랩 또는 IBT#CP예외 발생 시 커널 패닉 핸들러가 80 μs 이내에 전용 GPIO 핀을 통해 워치독 펄스를 차단함. - 서보 모터 버스 전원 차단 및 기계식 락:
- 모터 릴레이 전원을 소자하여 48V 전원을 0.0V로 강제 컷오프(Depower)함.
- 무여자 작동형 스프링 브레이크가 5ms 이내 물리 체결되어 로봇 관절의 회전 운동 에너지를 100% 흡수하고 정지시킴.
7. 공식 커널 문서 및 표준 보안 레퍼런스¶
- Linux Kernel Documentation - Control Flow Integrity (kCFI)
- Linux Kernel Documentation - x86 Indirect Branch Tracking (IBT)
- ARM Architecture Reference Manual - Branch Target Identification (BTI)
- CVE-2021-4154: Kernel Type Confusion Local Privilege Escalation (NIST NVD)
- Clang/LLVM Documentation - Kernel Control Flow Integrity