EuroLLVM’19 SRC Safely Optimizing Casts between Pointers and Integers Juneyoung Lee Seoul National Univ. Chung-Kil Hur MPI-SWS Ralf Jung Zhengyang Liu University of Utah John Regehr Nuno P. Lopes Microsoft Research 1
Overview Assembly LLVM IR (x86-64, ARM, ..) [0, 2 64 ) [0, 2 64 ) + provenance Pointer [0, 2 64 ) [0, 2 64 ) + ? Integer 2
Problem: Pointer as a Pure Integer We use C syntax for LLVM IR code for readability char p[1],q[1] = {0}; int ip = (int)(p+1); int iq = (int)q; if (iq == ip) { *(p+1) = 10; print(q[0]); } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer We use C syntax for LLVM IR code for readability char p[1],q[1] = {0}; int ip = (int)(p+1); int iq = (int)q; if (iq == ip) { *(p+1) = 10; print(q[0]); } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer We use C syntax for LLVM IR code for readability char p[1],q[1] = {0}; int ip = (int)(p+1); int iq = (int)q; if (iq == ip) { *(p+1) = 10; print(q[0]); } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer We use C syntax for LLVM IR code for readability char p[1],q[1] = {0}; int ip = (int)(p+1); int iq = (int)q; if (iq == ip) { *(p+1) = 10; print(q[0]); } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer We use C syntax for LLVM IR code for readability char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer Memory: 0x0 char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer - Memory: 0x0 0x100 0x100 char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer 0 - Memory: 0x0 0x100 0x101 0x100 0x101 char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer 0 - Memory: 0x0 0x100 0x101 0x100 0x101 char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; true if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer 0 - Memory: 0x0 0x100 0x101 0x100 0x101 char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); 0x101 int iq = (int)q; int iq = (int)q; true if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer 0 - 10 Memory: 0x0 0x100 0x101 0x100 0x101 char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); 0x101 int iq = (int)q; int iq = (int)q; true if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer 0 - 10 Memory: 0x0 0x100 0x101 0x100 0x101 char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); 0x101 int iq = (int)q; int iq = (int)q; true if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer 0 - 10 Memory: 0x0 0x100 0x101 0x100 0x101 char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); 0x101 int iq = (int)q; int iq = (int)q; true if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } 10 * https://godbolt.org/z/9eNt6w 3
Problem: Pointer as a Pure Integer 0 - 10 Memory: 0x0 0x100 0x101 0x100 0x101 char p[1],q[1] = {0}; Problem with “pointer as a pure integer” char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); 0x101 int iq = (int)q; int iq = (int)q; true if (iq == ip) { if (iq == ip) { Cannot protect accesses from different blocks *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } 10 * https://godbolt.org/z/9eNt6w 3
LLVM’s Solution: Pointers have Provenance - 0 0 Memory: 0x0 0x100 0x101 0x100 0x101 char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } * https://godbolt.org/z/9eNt6w 4
LLVM’s Solution: Pointers have Provenance Provenance Provenance - 0 p: - 0 0 q: 0 Memory: 0x0 0x100 0x100 0x101 0x101 (p,0x100) (q,0x101) char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } * https://godbolt.org/z/9eNt6w 4
LLVM’s Solution: Pointers have Provenance Provenance Provenance - 0 p: - 0 0 q: 0 Memory: 0x0 0x100 0x100 0x101 0x101 (p,0x100) (q,0x101) char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; true if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } * https://godbolt.org/z/9eNt6w 4
LLVM’s Solution: Pointers have Provenance Provenance Provenance - 0 p: - 0 0 q: 0 Memory: 0x0 0x100 0x100 0x101 0x101 (p,0x100) (q,0x101) char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; true if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } (p,0x101) * https://godbolt.org/z/9eNt6w 4
LLVM’s Solution: Pointers have Provenance Provenance Provenance - 0 p: - 0 0 q: 0 Memory: 0x0 0x100 0x100 0x101 0x101 (p,0x100) (q,0x101) char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; true if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } (p,0x101) * https://godbolt.org/z/9eNt6w 4
LLVM’s Solution: Pointers have Provenance Provenance Provenance - 0 p: - 0 0 q: 0 Memory: 0x0 0x100 0x100 0x101 0x101 (p,0x100) (q,0x101) char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; true if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); Undefined Behavior } prop. } (p,0x101) because p ≠ q * https://godbolt.org/z/9eNt6w 4
What about Integers? Assembly LLVM IR (x86-64, ARM, ..) [0, 2 64 ) [0, 2 64 ) + provenance Pointer Casting [0, 2 64 ) [0, 2 64 ) + ? Integer 5
Miscompilation with PtrIntCast char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } 6
Miscompilation with PtrIntCast char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } 6
Miscompilation with PtrIntCast int. eq. char p[1],q[1]={0}; char p[1],q[1]={0}; prop. int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(char*)(int)(p+1)=10; *(char*)iq = 10; print(q[0]); print(q[0]); } } cast elim. char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; constant print(q[0]); print(0); } prop. } 6
Miscompilation with PtrIntCast int. eq. char p[1],q[1]={0}; char p[1],q[1]={0}; prop. int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(char*)(int)(p+1)=10; *(char*)iq = 10; print(q[0]); print(q[0]); } } char p[1],q[1] = {0}; char p[1],q[1] = {0}; int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; if (iq == ip) { if (iq == ip) { *(p+1) = 10; *(p+1) = 10; print(q[0]); print(0); } } 7
Recommend
More recommend