Hardware-Assisted Run-Time Protection
Hardware-Assisted Run-Time Protection
Run-time Protection
N. Asokan†‡
https://asokan.org/asokan/
@nasokan
2
Example: Buffer overflows caused by
missing bounds checks
Software
Developer
08048464 <main>:
8048464: 55 push %ebp
8048465: 89 e5 mov %esp,%ebp
8048467: 68 20 85 04 08 push $0x8048520
804846c: e8 9f fe ff ff call 8048310 <puts@plt>
8048471: 83 c4 04 add $0x4,%esp
8048474: 8b 45 0c mov 0xc(%ebp),%eax
8048477: 83 c0 04 add $0x4,%eax
804847a: 8b 00 mov (%eax),%eax
804847c: 50 push %eax
804847d: 0804843b
e8 b9 <doit>:
ff ff ff call 804843b <doit>
int main(int argc, char *argv[]) 8048482: 83 c4
804843b: 04 55 add $0x4,%esp
push %ebp
{ 8048485: 68 31 85 04 89
804843c: 08 e5
push $0x8048531
mov %esp,%ebp
puts("So... The End..."); 804848a: e8 81 fe ff 83
804843e: ff ec
call
0c 8048310
sub <puts@plt>
$0xc,%esp
804848f: 83 c4 04
8048441: 8d 45add
f4 $0x4,%esp
lea -0xc(%ebp),%eax
doit(argv[1]);
puts("or... maybe not?"); Source Executable 8048492:
8048497:
b8 00 00 00 89
8048444:
c9
8048447:
00 45
ff 75
mov
fc
leave
08
$0x0,%eax
mov %eax,-0x4(%ebp)
pushl 0x8(%ebp)
8048498: c3 ret
return 0; code File 8048499:
804844a:
66 90
804844d:
8d 45
50 xchg
f4 lea
%ax,%ax
push
-0xc(%ebp),%eax
%eax
} 804849b: 66 90
804844e: e8 adxchg
fe ff%ax,%ax
ff call 8048300 <strcpy@plt>
void doit(char *str) 804849d: 66 90
8048453: 83 c4xchg
08 %ax,%ax
add $0x8,%esp
804849f: 90
8048456: ff 75nop
fc pushl -0x4(%ebp)
{
8048459: e8 b2 fe ff ff call 8048310 <puts@plt>
char buf[8];
804845e: 83 c4 04 add $0x4,%esp
char *ptr = buf; 8048461: 90 nop
Compiler & Linker 8048462: c9 leave
strcpy(buf, str); 8048463: c3 ret
puts(ptr);
}
strcpy(buf, str);
puts(ptr);
User }
0xffffffff
$ ./a.out “Hello !” parent stack frame
Kernel Space Kernel space
0xc0000000
Stack (grows down) =TASK_SIZE
08048464 <main>:
... User Space
8048474: 8b 45 0c mov 0xc(%ebp),%eax
8048477: 83 c0 04 add $0x4,%eax 0xbfffceb8
804847a: 8b 00 mov (%eax),%eax arguments: 0xbfffd18a (argv[1])
804847c: 50 push %eax 0xbfffceb4
804847d: e8 b9 ff ff ff call 804843b <doit> return address: 0x08048482 (saved eip)
0xbfffceb0 Memory Mapping
8048482: 83 <doit>:
0804843b c4 04 add $0x4,%esp frame pointer: 0xbfffceb8 (saved ebp) Region
8048485: 0x40000000
804843b: 31 85
68 55 04 08 push $0x8048531
push %ebp 0xbfffceac
804848a: e8
804843c: 81 fe
89 ff
e5 ff call 8048310%esp,%ebp
mov <puts@plt> ptr: 0xbfffcea0 (&buf)
804848f: 83 c4 04 add $0x4,%esp 0xbfffcea8
804843e: 83 ec 0c sub $0xc,%esp ’\0’ ’!’ ’ ’ ’O’
8048492: b8
8048441: 00 00
8d 00
45 00
f4 mov $0x0,%eax
lea -0xc(%ebp),%eax 0xbfffcea4
8048497: c9
8048444: 89 45 fc leavemov %eax,-0x4(%ebp) buf: ’L’ ’L’ ’E’ ’H’
8048498: c3 ret 0xbfffcea0
8048447: ff 75 08 pushl 0x8(%ebp) arguments: 0xbfffcea0 (ptr) Heap (grows up)
8048499: 66 90 8d 45 f4
804844a: xchg %ax,%ax-0xc(%ebp),%eax
lea 0xbfffce9c
804849b: 66 90 50 xchg %ax,%ax%eax 0xbfffd18a (str) Bss segment
804844d: push
804849d: 66 90 e8 ad fe xchg %ax,%ax8048300 <strcpy@plt> 0xbfffce98
804844e: ff ffcall Data segment
804849f: 90 nop strcpy stack frame
8048453: 83 c4 08 add $0x8,%esp
8048456: ff 75 fc pushl -0x4(%ebp) Text segment
8048459: e8 b2 fe ff ff call 8048310 <puts@plt>
804845e: 83 c4 04 add $0x4,%esp 0x0804000
8048461: 90 nop 0x00000000
8048462: c9 leave
8048463: c3 ret
4
void doit(char *str)
{
Control-flow hijacking char buf[8];
char *ptr = buf;
strcpy(buf, str);
."\x??\x??\x04\x08"
"\x??\x??\x04\x08" \
."A"x4
"A"x4 \
0xffffffff
parent stack frame
Kernel Space Kernel space
."\x64\x84\x04\x08"')
"\x64\x84\x04\x08" 0xc0000000
Stack (grows down) =TASK_SIZE
libc init:
User Space
0xbfffceb8
arguments: 0xbfffd18a (argv[1])
0xbfffceb4
08048464:
return address: 0x08048464 (main)
0x08048482 (saved eip)
<main>: 0xbfffceb0 Memory Mapping
frame pointer: 0xffffceb8
’A’ ’A’ (saved
’A’ ebp)
’A’ Region
0xbfffceac 0x40000000
ptr: 0x0804????
0xffffcea0 (&buf)
(data)
0xbfffcea8
0804843b: ’A’
’\0’ ’!’
’A’ ’ ’
’A’ ’O’
’A’
0xbfffcea4
<doit>: ’L’
buf: ’A’ ’L’
’A’ ’E’
’A’ ’H’
’A’
0xbfffcea0
0xbfffcea0 (ptr) Heap (grows up)
0xbfffce9c
0xbfffd18a (str) Bss segment
0x8048300: 8048310:
strcpy stack frame Data segment
<strcpy>: puts:
Text segment
0x08040000
0x00000000
corrupt code pointer /
control flow 5
Memory-related
run-time attacks
Memory-related run-time attacks
7
Run-time attacks compromise program behaviour
Adversary
exploits bug
1 if (authenticated != true)
then: call unprivileged()
…
else: call privileged() 1
2 unprivileged() { … }
3 privileged() { … } 2 3 shellcode
…
8
(i) Code-injection attacks
Countermeasures:
shellcode
• Stack canaries (1990) frame- badreturn
return
address
address
stack frame
record frame-pointer
Detect sequential overwrites that corrupt ret. addr. FP
• W⊕X memory access control policy (2003)
Prevent execution of shellcode by ensuring that buffer
SP
memory pages are either writable or executable
Elias Levy (as Aleph One), Smashing the stack for fun and profit, Phrack 7 (1996)
Cowan et al., StackGuard: Automatic adaptive detection and prevention of buffer-overflow attacks, USENIX Security (1998) 9
Szekeres et al., SoK: Eternal War in Memory, IEEE SP (2013)
void doit(char *str)
{
Classic code-injection char buf[8];
char *ptr = buf;
strcpy(buf, str);
puts(ptr);
$ ./a.out $(perl -e 'print "A"x8 \ }
."\x??\x??\x04\x08"
"\x??\x??\x04\x08" \
."A"x4
"A"x4 \ 0xffffffff
."\xb8\xce\xff\xfb"
"\xb8\xce\xff\xfb" \ parent stack frame
Kernel space
."\x80\xcd" ."\x40“ \ 0xc0000000
0xbfffcebc Stack (grows down)
."\xc0\x31" ."\x80\xcd" \ =TASK_SIZE
libc init: ."\x0b\xb0" ."\xc2\x89" \
."\xc1\x89" ."\xe3\x89" \ shellcode
0xbfffceb8
."\x6e\x69\x62\x2f\x68" \ 0xffffd18a (argv[1])
08048464: ."\x68\x73\x2f\x2f\x68" \ 0xbfffceb8
0x08048482 (saved eip)
0xbfffceb4
<main>:
."\x50" ."\xc0\x31") ’A’ ’A’ (saved
0xffffceb8 ’A’ ebp)
’A’
0xbfffceb0 Memory Mapping
Region
0xbfffceac 0x40000000
0xffffcea0 (&buf)
0x0804???? (data)
0xbfffcea8
0804843b: ’A’
’\0’ ’!’
’A’ ’ ’
’A’ ’O’
’A’
<doit>:
:0xffffceb8
:<shellcode> ’L’
’A’ ’L’
’A’ ’E’
’A’ ’H’
’A’
0xbfffcea4
0xbfffcea0
Heap (grows up)
0xbfffcea0 (ptr)
0xbfffce9c
0xbfffd18a (str) Bss segment
0x8048300: 8048310:
strcpy stack frame Data segment
<strcpy>: puts:
Text segment
0x0804000
0x00000000
10
Return-oriented programming (high-level idea)
…
push edi
Adversary
leave
ret
exploits bug
…
cmp eax,edi
leave
ret
… …
mov eax,[ebp+0x8] cmp [esi+0x74],edi
leave … leave
ret add $0x4,%esp ret
leave 12
ret
(ii) Code-reuse attacks
…
gadget 3:
Exploit memory error without injecting code: br <puts>
ret
• Corrupt code pointer (usually return address) to …
address of gadget 3
redirect execution flow to existing code: gadget 2:
• Library functions (return-into-libc) forged data load x0, x0
• Pre-existing instruction sequences (gadgets) address of gadget 2 ret
…
forged data
function:
gadget 1:
Countermeasures: frame- address
address of
returnof function
address
gadget 1 …
load x0, sp
stack frame
• Control-flow Integrity (2005) record frame-pointer ret
FP
Detect control-flow transfers outside static SP+size
control-flow graph or mismatched returns
buffer
(shadow stack) SP
CFI check at G
G Allowed edges: (G,C), (G,D)
Legend:
intended forward-edge in CFG initial node in CFG
intended backward-edge in CFG node in CFG
malicious edge not part of CFG 15
Shadow Stack: High-level idea
shadow stack
B
A→B→C
C
16
void doit(char *str)
{
Non-control data attack char buf[8];
char *ptr = buf;
strcpy(buf, str);
."\x08\xb0\xc4\x09"
"\x08\xb0\xc4\x09" )
0xffffffff
parent stack frame
Kernel space
0xc0000000
Stack (grows down) =TASK_SIZE
libc init:
0xbfffceb8
0xffffceb8
arguments: 0xbfffd18a (argv[1])
0xbfffceb4
08048464:
return address: 0x08048482 (saved eip)
<main>: 0xbfffceb0 Memory Mapping
frame pointer: 0xbfffceb8 (saved ebp) Region
0xbfffceac 0x40000000
ptr: 0x09c4b008 (&buf)
0xffffcea0 (in heap)
0xbfffcea8
0804843b: ’A’
’\0’ ’!’
’A’ ’ ’
’A’ ’O’
’A’
0xbfffcea4
<doit>: ’L’
buf: ’A’ ’L’
’A’ ’E’
’A’ ’H’
’A’
0xbfffcea0
0xbfffcea0 (ptr) Heap (grows up)
0xbfffce9c
0xbfffd18a (str) Bss segment
0x8048300: 8048310:
strcpy stack frame Data segment
<strcpy>: puts:
Text segment
0x0804000
0x00000000
Program logic that can be influenced Attacker influences the behavior of
as result of memory vulnerability benign program code without breaking 17
constitute “data-oriented gadgets” control-flow integrity
Data-oriented Programming
Enables expressive computation via use of “data-oriented gadgets” without diverging
from program’s benign control-flow
• Requires a “gadget dispatch” that allows chaining together gadgets at will
loop Adversary
selector exploits bug
data-oriented program
…
#2
copy()
…
#1
#1 #2
#2 #3
#3 …
load()
… …
store()
… 18
Data-oriented programming
Given a suitable gadget dispatch, Dispatch must be able to
an attacker can chain together chain data-oriented gadgets
0xffffffff
data-oriented gadgets at will without violating control-flow
Kernel space
0xc0000000
Stack (grows down) =TASK_SIZE
Memory Mapping
Region
loop selector 0x40000000
#1
#2 #1 #1
Heap (grows up)
Bss segment
#2 Data segment
Text segment
0x0804000
#3 #3 0x00000000
Software
Integrity Modify Modify Code-pointer Modify non-
❷ Exfiltrate data Code Integrity Compart-
violation code control-data Integrity control-data
mentalization
Exploit Interpret Inject attacker- Instruction Set Inject attacker- Address-space Inject attacker- Software
❸
Payload exfiltrated data controlled code
Randomization controlled address
Randomization controlled data Diversification
Control-
Exploit Indirect jump to Return to Use of corrupt Data-flow
❹ flow
Dispatch corrupt address corrupt address
Integrity
data Integrity
Exploit Binary Execute Execute injected Execute gadget Execute data- Run-time
❺
Execution Attestation modified code code fragment / code fragment oriented gadget Attestation
Virtual machines
24
Protect against run-time attacks
without incurring a significant
performance penalty
25
Design new hardware-security mechanisms
Example: HardScope
Enforce variable visibility rules at run time
Mitigate effects of attacks that corrupt data-plane information
Digital design, FPGA realization, compiler instrumentation, extensive analysis
Deployment challenge:
• Required the addition of 7 new instructions to the RISC-V ISA
Nyman et al. HardScope: Hardening Embedded Systems Against Data-Oriented Attacks. DAC 2019
26
Hardware assisted defenses in CotS processors
27
ARMv8-A mechanisms
Pointer Integrity: memory safety for pointers
PA Key PA
PAuth management Instructions
configuration register
64-bit modifier (M)
32
ARM. Arm® Architecture Reference Manual Armv8, for Armv8-A architecture profile. Version E.a. July 2019
ARMv8.3-A PA – Key management and instructions
34
Example: -msign-return-address
Deployed in GCC 5.0 and LLVM/Clang 7.0
return address
func {
Function return address pacia LR, SP generate PAC ia key
stack frame
record frame-pointer
• Does not require reference value FP
• Can be bound to contextual information (e.g., the SP value)
buffer
• Protects return address against arbitrary writes SP
37
Liljestrand et al, Protecting the stack with PACed canaries. SysTEX@SOSP 2019
PA only approximates fully-precise pointer integrity
Adversary may reuse PACs
func1 {
pacia LR, SP
str LR ..ab08
… ..ab10
… ..ab18
SP
/* func1() */ ..ab20 func2 stack frame
func1
..ab28 PAC+ret_address_1
PAC+ret_address_2
brl %func1 func2 {
..ab30
..ab38
… pacia LR, SP
..ab40
..ab48
/* func2() */ str LR
..ab50
… ldr LR
autia LR, SP
pacia – add PAC ret
autia – authenticate }
38
PARTS
Modifier: based on pointer type // ptr = …
• Assigned at compile-time based on C type …
• “this pointer really points to this type of data or function” mov Xmod, #type_id
On-use or on-load authentication pacia Xptr, Xmod
• Branching with combined auth+branch instruction (blraa)
• Iterating an array uses only one authentication
PACed only on pointer creation!
// *ptr // ptr();
… Authenticated on load …
Authenticated on use
ldr Xptr, [Addr] …
pacda – add PAC with data A-key mov Xmod, #type_id mov Xmod, #type_id
autda – authentic§ate
autda Xptr, Xmod blraa Xptr, Xmod
pacia – add PAC with instr A-key
blraa – authenticate and branch ldr Xd [Xptr] …
39
Liljestrand et al. PAC it up: Towards Pointer Integrity using ARM Pointer Authentication USENIX Security (2019)
Authenticated Call Stack: high-level idea
In dedicated register
Address Allocation
MTE tags tags
Ensures memory accesses are safe by comparing tag in pointer with tag in memory
• Can prevent seqential buffer overflows, and (with high probability) other memory errors
return 0;
} 0xffffceb8
void doit(char *str) return address: doit stack
0x08048482 frame
(saved LR)
{ 0xffffceb0
frame pointer: 0xffffceb8 (saved FP)
0xffffcea8
char buf[16];
ptr: 0xffffce88 (&buf)
char ptr = buf; 0xffffcea0
Provides:
• Deterministic prevention of sequential overflows
• Probabilistic detection of use-after-free and non-sequential out-of-bounds
• In the general case: 1-2-4 ≈ 0.94 chance of detection
E. Stepanov et al., Memory tagging in LLVM and Android, LLVM Developers’ Meeting (2020)
LLVM, MemTagSanitizer, online documentation 49
LLVM, Stack Safety Analysis, online documentation
LLVM Stack Safety Analysis
Introduced by Kuznetsov et al. but also Algorithm finds access range of pointers
used to optimize MTE instrumentation • If range is within allocated memory,
then allocation is provably safe
Memory safety loosely defined as: • Local analysis
A memory object is safe, if all pointers derived • Determines local use ranges for
from it are guaranteed to only access the memory allocations and function arguments
object itself.
• Global analysis
• Merges ranges from function arguments
Does not preclude safe object corruption
• Runs until fixed point reached
• by unrelated unsafe memory accesses
• by within-allocation memory corruption
Pointers in memory assumed unsafe!
51
LLVM, MemTagSanitizer, online documentation
Our goal
52
Preventing tag corruption
Always set one tag-bit on load from memory // Load ptr1 from ptr2
• Prevents injection of “safe” tags (costs one tag-bit) char *ptr1 = *ptr2;
Alternatively use ARM Pointer Authentication // Apply ptr2 tag bits to ptr1
• Probabilistic but does not reserve one tag-bit ptr1 = ptr1 | (tag & ptr2);
53
MTE-aware analysis
memory guard
0x00..ffffde80
Analysis checks that for any sequential access strcpy stack frame
• start_range ⊆ allocated_memory
• max_step < memory_guard_size
54
Analysis of in-memory pointers
55
R. Gil et al., There’s a hole in the bottom of the C: on the effectiveness of allocation protection, SecDev (2018)
MTE-aware analysis with in-memory pointers
BTI
ARM. Arm® Architecture Reference Manual Armv8, for Armv8-A architecture profile. Version E.a. July 2019 57
ARMv8.5-A BTI
Branch sources
BTI call type branches
BLR … Indirect function calls
BR <x16|x17> PLT entries and tail calls
BTI jump type branches
BR … (except x16|x17) Branches to jump tables
BTI Marker Instructions
BTI <c|j|cj> Branch Target Identification for c=calls, j=jumps, cj=calls or jumps
BRK Breakpoint Instruction
HLT Halting breakpoint
PACIASP / PACIBSP Create PAC for Instruction address in LR using key A/B and SP as modifier
ARM. Arm® Architecture Reference Manual Armv8, for Armv8-A architecture profile. Version E.a. July 2019 58
Taxonomy of Defenses
Out-of-bounds Dangling Format string
pointer pointer vulnerability
Memory MTE PAuth
❶
vulnerability Memory-safety
Unintended Unintended
Read Write
Software
Integrity Modify Modify Code-pointer Modify non-
❷ Exfiltrate data Code Integrity Compart-
violation code control-data Integrity control-data
mentalization
Exploit Interpret Inject attacker- Instruction Set Inject attacker- Address-space Inject attacker- Software
❸
Payload exfiltrated data controlled code
Randomization controlled address
Randomization controlled data Diversification
Control-
Exploit BTI Indirect jump to Return to Use of corrupt Data-flow
❹ flow
Dispatch corrupt address corrupt address
Integrity
data Integrity
Exploit Binary Execute Execute injected Execute gadget Execute data- Run-time
❺
Execution Attestation modified code code fragment / code fragment oriented gadget Attestation
Skip to CET
Intel Memory Protection Extension
Bound
Bound
MPX Check
Directory
ISA
Intel. Intel® 64 and IA-32 Architectures Software Developer Manuals. Volume 1. Chapter 17. May 2019
61
Intel MPX – Example
2: total = 0
3: for (i=0; i<M; i++):
4: ai = a + i // Pointer arithmetic on a
5: objptr = load ai // Pointer to obj at a[i]
6: lenptr = objptr + 100 // Pointer to obj.len
7: len = load lenptr
8: total += len // Total length of all objs
62
Intel MPX – Bound Check Instructions
MPX Registers
BND00 – BND03 Bound Registers storing 64-bit LowerBound (LB) and 64-bit UpperBound (UB)
MPX Instructions
BNDMK <Reg> <Addr> <offset> Create LB (Addr) and UB (Addr + offset) in Reg
Bound Check Instructions
BNDCL <Reg> <Addr> Check Addr against LB in Reg .
BNDCU <Reg> <Addr> Check Addr against UB in Reg in 1’s compliment form
BNDCN <Reg> <Addr> Check Addr against UB in Reg not in 1’s compliment form
Bound Management Instructions
BNDMV <Reg> <Reg|Addr> Copy LB and UB from Reg or Addr to Reg
BNDMV <Addr> <Reg> Store LB and UB from Reg to Addr
BNDLDX <Reg> <SIB> Load LB and UB from bound directory
BNDSTX <SIB> <Reg> Store LB and UB to bound directory
Intel. Intel® 64 and IA-32 Architectures Software Developer Manuals. Volume 1. Chapter 17.4. May 2019
63
Intel MPX – Example struct obj { char buf[100]; int len }
obj* a[10]
1: for (i=0; i<M; i++) {
2: total += a[i]->len;
3: }
21+MAWA GBytes
Intel. Intel® 64 and IA-32 Architectures Software Developer Manuals. Volume 1. Chapter 17.4.3.1 May 2019
65
Intel MPX – Limitations
Oleksenko et al. Intel MPX Explained: A Cross-layer Analysis of the Intel MPX System Stack. SIGMETRICS ’18
Canella et al. A Systematic Evaluation of Transient Execution Attacks and Defenses. USENIX Sec ‘19
66
https://ssg.aalto.fi/research/projects/kernel-hardening/
Reshetova et al. Towards Linux Kernel Memory safety. Software: Practice and Experience, Volume 48, Issue12. 2018 67
Intel Protection Keys for Userspace
PKU
Intel. Intel® 64 and IA-32 Architectures Software Developer Manuals. Volume 1. Chapter 2.7., 4.6.2 May 2019
68
Intel PKU – Instructions
PKU Registers
PKRU Protection Key Right Register
write disable
access disable
PKU Instructions
RDPKRU Read PKRU value to EAX
WRPKRU Write EAX value to PKRU
Intel. Intel® 64 and IA-32 Architectures Software Developer Manuals. Volume 1. Chapter 2.7., 4.6.2 May 2019
69
Intel Control-flow Enforcement Technology
Shadow Indirect
CET Stack
Branch
Tracking
Intel. Control-flow Enforcement Technology Specification, Revision 3.0. Chapter 2. May 2019
71
Skip to taxonomy
Intel CET – Indirect Branch Tracking
ENDBRANCH<Mode> WAIT_FOR_
or legacy mode
ENDBRANCH
Requires indirect JMP / CALL to target specific marker instructions
• compiler places marker at all potential indirect branch targets
• new control-protection exception (#CP) raised otherwise Generate
#CP fault
IBT Marker Instructions
ENDBRANCH32 Marker instruction in 32-bit mode
ENDBRANCH64 Marker instruction in 64-bit mode
Intel. Control-flow Enforcement Technology Specification, Revision 3.0. Chapter 3. May 2019
73
Taxonomy of Defenses
Out-of-bounds Dangling Format string
pointer pointer vulnerability
Memory MPX
❶
vulnerability Memory-safety
Unintended Unintended
Read Write
Software
Integrity Modify Modify Code-pointer Modify non-
❷ Exfiltrate data Code Integrity Compart-
violation code control-data Integrity control-data
mentalization
Exploit Interpret Inject attacker- Instruction Set Inject attacker- Address-space Inject attacker- Software
❸
Payload exfiltrated data controlled code
Randomization controlled address
Randomization controlled data Diversification
Control-
Exploit CET Indirect jump to Return to Use of corrupt Data-flow
❹ flow
Dispatch corrupt address corrupt address
Integrity
data Integrity
Exploit Binary Execute Execute injected Execute gadget Execute data- Run-time
❺
Execution Attestation modified code code fragment / code fragment oriented gadget Attestation
Skip to PA vs CET
Intel MPX vs. ARMv8.5-A MTE
76
Intel CET ShadowStack vs. ARMv8.3-A PA
*) Liljestrand et al. PAC It Up: Towards Pointer Integrity using ARM Pointer Authentication. USENIX Security’19
**) Liljestrand et al. PACStack: an Authenticated Call Stack. Usenix Security (2021)
77
Skip to theory
Intel IBT vs. ARMv8.3-A BTI
79
A theory of run-time attacks
von Neumann architecture
Output
Device
Device
(math)
Input
With a large addressable memory, different memory types (e.g.
SRAM, DRAM flash etc.) and I/O map onto single memory space PC CIR
Registers AC MAR MDR
L2 Memory
L3 Memory
Memory
81
Programs as intended finite state machines
Design of program 𝒑𝒑 can be modeled as (potentially very large) finite state machine†,‡
• The intended finite state machine (IFSM) describes the intended function of 𝒑𝒑
• To execute the IFSM on real-world computers, 𝒑𝒑 is realized as a software emulator for the IFSM
𝑸𝑸𝑰𝑰𝑰𝑰𝑰𝑰𝑰𝑰
𝒄𝒄𝒄𝒄𝒄𝒄 : concrete states of target
machine that map to a state in
the IFSM
𝑸𝑸𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕
𝒄𝒄𝒄𝒄𝒄𝒄 𝑸𝑸𝑰𝑰𝑰𝑰𝑰𝑰𝑰𝑰
𝒄𝒄𝒄𝒄𝒄𝒄
𝑸𝑸𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕
𝒄𝒄𝒄𝒄𝒄𝒄 : benign transitory states
that occur during emulation of
an edge in the IFSM; part of
intended transitions
83
T. F. Dullien, Weird machines, exploitability, and provable unexploitability, IEEE Transactions on Emerging Topics in Computing (2017)
Two different perspectives of 𝜽𝜽
data
input input
State 1 State 2 State 3 State 4 State 5
instruction instruction instruction instruction
Program 𝒑𝒑
input input
State 1 State 4 State 5
instruction instruction instruction instruction
input input
State 1 State 2 State 3 State 4 State 5
instruction instruction instruction instruction
Program 𝒑𝒑
input input
State 1 State ? State ?
instruction instruction instruction instruction
𝑸𝑸𝑰𝑰𝑰𝑰𝑰𝑰𝑰𝑰
𝒄𝒄𝒄𝒄𝒄𝒄 : concrete states of target
machine that map to a state in
the IFSM
𝑸𝑸𝒘𝒘𝒆𝒆𝒆𝒆𝒆𝒆𝒅𝒅
𝒄𝒄𝒄𝒄𝒄𝒄 : set of stats in 𝑸𝑸𝒄𝒄𝒄𝒄𝒄𝒄
not in 𝑸𝑸𝑰𝑰𝑰𝑰𝑰𝑰𝑰𝑰 𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕
𝒄𝒄𝒄𝒄𝒄𝒄 nor 𝑸𝑸𝒄𝒄𝒄𝒄𝒄𝒄
𝑸𝑸𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕
𝒄𝒄𝒄𝒄𝒄𝒄 𝑸𝑸𝑰𝑰𝑰𝑰𝑰𝑰𝑰𝑰
𝒄𝒄𝒄𝒄𝒄𝒄 𝑸𝑸𝒘𝒘𝒆𝒆𝒆𝒆𝒓𝒓𝒓𝒓
𝒄𝒄𝒄𝒄𝒄𝒄
86
T. F. Dullien, Weird machines, exploitability, and provable unexploitability, IEEE Transactions on Emerging Topics in Computing (2017)
Reaching a weird state
𝒒𝒒𝒊𝒊𝒊𝒊𝒊𝒊𝒊𝒊 ∈ 𝑸𝑸𝒘𝒘𝒘𝒘𝒊𝒊𝒓𝒓𝒓𝒓
𝒄𝒄𝒄𝒄𝒄𝒄
A weird machine is a computational device where IFSM transitions operate on weird states
𝜽𝜽𝒘𝒘𝒘𝒘𝒘𝒘𝒘𝒘𝒘𝒘 = 𝑸𝑸𝒘𝒘𝒘𝒘𝒘𝒘𝒘𝒘𝒘𝒘
𝒄𝒄𝒄𝒄𝒄𝒄 , 𝒒𝒒 𝒊𝒊𝒊𝒊𝒊𝒊𝒊𝒊 , 𝑸𝑸 𝑰𝑰𝑰𝑰𝑰𝑰𝑰𝑰 ∪ 𝑸𝑸𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕𝒕 , 𝚺𝚺𝚺, 𝚫𝚫𝚫, 𝜹𝜹𝜹, 𝝈𝝈𝝈
𝒄𝒄𝒄𝒄𝒄𝒄 𝒄𝒄𝒄𝒄𝒄𝒄
88
T. F. Dullien, Weird machines, exploitability, and provable unexploitability, IEEE Transactions on Emerging Topics in Computing (2017)
Possible sources of weird states
T. F. Dullien, Weird machines, exploitability, and provable unexploitability, IEEE Transactions on Emerging Topics in Computing (2017)
89
Y. Kim et al., Flipping Bits in Memory Without Accessing Them: An Experimental Study of DRAM Disturbance Errors, ISCA (2014)
Modelling the attacker
90
T. F. Dullien, Weird machines, exploitability, and provable unexploitability, IEEE Transactions on Emerging Topics in Computing (2017)
Defining security
Depends on the desired security goal of 𝜽𝜽 and 𝑝𝑝 : e.g., not disclose sensitive
information s
Attacker wins if s is in the output of 𝜽𝜽weird with a higher probability than random
91
T. F. Dullien, Weird machines, exploitability, and provable unexploitability, IEEE Transactions on Emerging Topics in Computing (2017)
Takeaways
New hardware-assisted defenses are emerging and are (going to be) widely available
Icons on slides 3, 4, 5, 15, 16, 17, 19, 21, 22, 23 and 24 made by Good Ware from www.flaticon.com
licensed by CC 3.0 BY
The PHP logo on slide 25 made by Colin Viebrock licensed by CC BY-SA 4.0
All product and company names and logos are trademarks™ or registered ® trademarks of their
respective holders. Use of them does not imply any affiliation with or endorsement by them.