Taming Undefined Behavior in LLVM
Nuno P. Lopes
PLDI 2017 Barcelona
Seoul National Univ. Juneyoung Lee Yoonseung Kim Youngju Song Chung-Kil Hur Azul Systems Sanjoy Das Google John Regehr University of Utah David Majnemer Microsoft Research
Taming Undefined Behavior in LLVM Juneyoung Lee Yoonseung Kim - - PowerPoint PPT Presentation
PLDI 2017 Barcelona Taming Undefined Behavior in LLVM Juneyoung Lee Yoonseung Kim Seoul National Univ. Youngju Song Chung-Kil Hur Sanjoy Das Azul Systems Google David Majnemer University of Utah John Regehr Nuno P. Lopes Microsoft
Nuno P. Lopes
PLDI 2017 Barcelona
Seoul National Univ. Juneyoung Lee Yoonseung Kim Youngju Song Chung-Kil Hur Azul Systems Sanjoy Das Google John Regehr University of Utah David Majnemer Microsoft Research
/ 21
2
/ 21
3
/ 21
int* p int a int b
IR IR
4
Motivation for UB
/ 21
int* p int a int b
IR IR
0x100 0x100 0xFFFFFF00
4
Motivation for UB
/ 21
int* p int a int b
IR IR
0x0 (Overflow!)
0x100 0x100 0xFFFFFF00
4
Motivation for UB
/ 21
int* p int a int b
IR IR
false
0x0 (Overflow!)
0x100 0x100 0xFFFFFF00
4
Motivation for UB
/ 21
int* p int a int b
IR IR
false true
0x0 (Overflow!)
0x100 0x100 0xFFFFFF00
4
Motivation for UB
/ 21
int* p int a int b
IR IR
false true
0x0 (Overflow!)
0x100 0x100 0xFFFFFF00
4
UB
Motivation for UB
/ 21
5
... for(i=0; i<n; ++i) { a[i] = p + 0x100 } q = p + 0x100 for(i=0; i<n; ++i) { a[i] = q }
IR IR
Problems with UB
/ 21
5
... for(i=0; i<n; ++i) { a[i] = p + 0x100 } q = p + 0x100 for(i=0; i<n; ++i) { a[i] = q }
IR IR
0xFFFFFF00 0xFFFFFF00
Problems with UB
/ 21
5
... for(i=0; i<n; ++i) { a[i] = p + 0x100 } q = p + 0x100 for(i=0; i<n; ++i) { a[i] = q }
IR IR
0xFFFFFF00 0xFFFFFF00 Overflow!
Problems with UB
/ 21
5
... for(i=0; i<n; ++i) { a[i] = p + 0x100 } q = p + 0x100 for(i=0; i<n; ++i) { a[i] = q }
IR IR
0xFFFFFF00 0xFFFFFF00 Overflow!
UB
Problems with UB
/ 21
6
/ 21
7
... for(i=0; i<n; ++i) { a[i] = p + 0x100 } q = p + 0x100 for(i=0; i<n; ++i) { a[i] = q }
IR IR
0xFFFFFF00 0xFFFFFF00 Overflow!
UB
/ 21
7
... for(i=0; i<n; ++i) { a[i] = p + 0x100 } q = p + 0x100 for(i=0; i<n; ++i) { a[i] = q }
IR IR
0xFFFFFF00 0xFFFFFF00 Overflow! poison
UB
/ 21
7
... for(i=0; i<n; ++i) { a[i] = p + 0x100 } q = p + 0x100 for(i=0; i<n; ++i) { a[i] = q }
IR IR
0xFFFFFF00 0xFFFFFF00 Overflow! poison
UB
/ 21
IR IR
0xFFFFFF00 0x100 0x100 0
8
UB
0x0 (Overflow!)
/ 21
IR IR
0xFFFFFF00 0x100 0x100 0
8
UB
0x0 (Overflow!)
Poison
/ 21
IR IR
0xFFFFFF00 0x100 0x100 0
8
UB
0x0 (Overflow!)
Poison
/ 21
IR IR
0xFFFFFF00 0x100 0x100 0
8
UB UB
0x0 (Overflow!)
Poison
/ 21
9
p a p b + + >
0xFFFFFF00 0x100
/ 21
9
p a p b + + >
0xFFFFFF00 0x100
/ 21
9
p a p b + + >
0xFFFFFF00 0x100
Propagate
/ 21
9
p a p b + + >
0xFFFFFF00 0x100
Propagate Raise UB
UB
/ 21
9
p a p b + + >
0xFFFFFF00 0x100
Propagate Raise UB
“Poison is Sometimes Too Poisonous” UB
/ 21
10
if (x == y) { .. use x .. } if (x == y) { .. use y .. }
Problems with LLVM’s UB
/ 21
10
if (x == y) { .. use x .. } if (x == y) { .. use y .. }
Problems with LLVM’s UB
/ 21
10
if (x == y) { .. use x .. } if (x == y) { .. use y .. }
Problems with LLVM’s UB
/ 21
10
if (x == y) { .. use x .. } if (x == y) { .. use y .. }
Problems with LLVM’s UB
/ 21
10
if (x == y) { .. use x .. } if (x == y) { .. use y .. }
Problems with LLVM’s UB
/ 21
10
if (x == y) { .. use x .. } if (x == y) { .. use y .. }
Problems with LLVM’s UB
UB
/ 21
10
if (x == y) { .. use x .. } if (x == y) { .. use y .. }
Problems with LLVM’s UB
UB
/ 21
10
if (x == y) { .. use x .. } if (x == y) { .. use y .. }
Problems with LLVM’s UB
UB UB
/ 21
11
while (n > 0) { if (cond) A else B } if (cond) while (n > 0) { A } else while (n > 0) { B }
Problems with LLVM’s UB
/ 21
11
while (n > 0) { if (cond) A else B } if (cond) while (n > 0) { A } else while (n > 0) { B }
Problems with LLVM’s UB
/ 21
11
while (n > 0) { if (cond) A else B } if (cond) while (n > 0) { A } else while (n > 0) { B }
Problems with LLVM’s UB
UB
/ 21
12
/ 21
13
/ 21
14
Existing Approaches
Defined values
Poison values
Can’t Control Poison
GVN + LU
More Defined Complex Inconsistent
UB
/ 21
14
𝒈𝒔𝒇𝒇𝒜𝒇
Existing Approaches Our Approach
Defined values
Poison values Defined values Poison values
Can’t Control Poison
GVN + LU
More Defined Complex Inconsistent Simpler
UB UB
/ 21
14
𝒈𝒔𝒇𝒇𝒜𝒇
Existing Approaches Our Approach
Defined values
Poison values Defined values Poison values
Can’t Control Poison
GVN + LU
More Defined Can Control Poison Complex Inconsistent Simpler
UB UB
/ 21
14
𝒈𝒔𝒇𝒇𝒜𝒇
Existing Approaches Our Approach
Defined values
Poison values Defined values Poison values
Can’t Control Poison
GVN + LU
More Defined Can Control Poison Complex Inconsistent Simpler Consistent
UB UB
/ 21
15
y = freeze x When x is a defined value: When x is a poison value: freeze x freeze x
1 2 . . .
x
A Defined Value
/ 21
if (freeze(cond)) while (n > 0) { A } else while (n > 0) { B } (cond)
16
while (n > 0) { if (cond) A else B }
Our Solution
UB
/ 21
if (freeze(cond)) while (n > 0) { A } else while (n > 0) { B }
16
while (n > 0) { if (cond) A else B }
Our Solution
UB
/ 21
if (freeze(cond)) while (n > 0) { A } else while (n > 0) { B }
16
while (n > 0) { if (cond) A else B }
Our Solution
UB
/ 21
if (freeze(cond)) while (n > 0) { A } else while (n > 0) { B }
16
while (n > 0) { if (cond) A else B }
Our Solution
UB
/ 21
17
/ 21
17
/ 21
// bitwise-or k = x | 0x1 t = 100 / k while (n > 0) use(t)
18
// bitwise-or k = x | 0x1 while (n > 0) use(100 / k)
Further Example
/ 21
// bitwise-or k = x | 0x1 t = 100 / k while (n > 0) use(t)
18
// bitwise-or k = x | 0x1 while (n > 0) use(100 / k)
Further Example
/ 21
// bitwise-or k = x | 0x1 t = 100 / k while (n > 0) use(t)
18
// bitwise-or k = x | 0x1 while (n > 0) use(100 / k)
Further Example
/ 21
// bitwise-or k = x | 0x1 t = 100 / k while (n > 0) use(t)
18
// bitwise-or k = x | 0x1 while (n > 0) use(100 / k)
Further Example
/ 21
// bitwise-or k = x | 0x1 t = 100 / k while (n > 0) use(t)
18
// bitwise-or k = x | 0x1 while (n > 0) use(100 / k)
Further Example
UB
/ 21
// bitwise-or k = x | 0x1 t = 100 / k while (n > 0) use(t)
18
// bitwise-or k = x | 0x1 while (n > 0) use(100 / k)
Further Example
UB
/ 21
// bitwise-or k = x | 0x1 t = 100 / k while (n > 0) use(t)
18
// bitwise-or k = x | 0x1 while (n > 0) use(100 / k)
Further Example
/ 21
// bitwise-or k = x | 0x1 t = 100 / k while (n > 0) use(t) freeze(x) | 0x1
18
// bitwise-or k = x | 0x1 while (n > 0) use(100 / k)
Further Example
/ 21
// bitwise-or k = x | 0x1 t = 100 / k while (n > 0) use(t) freeze(x) | 0x1
18
// bitwise-or k = x | 0x1 while (n > 0) use(100 / k)
Further Example
A defined value
/ 21
// bitwise-or k = x | 0x1 t = 100 / k while (n > 0) use(t) freeze(x) | 0x1
18
// bitwise-or k = x | 0x1 while (n > 0) use(100 / k)
Further Example
A defined value non-zero
/ 21
// bitwise-or k = x | 0x1 t = 100 / k while (n > 0) use(t) freeze(x) | 0x1
18
// bitwise-or k = x | 0x1 while (n > 0) use(100 / k)
Further Example
A defined value non-zero
/ 21
19
* More details are given in the paper
/ 21
20
* More details are given in the paper
/ 21
20
* More details are given in the paper
/ 21
21