# Safely Optimizing Casts between Pointers and Integers Juneyoung Lee - PowerPoint PPT Presentation

## EuroLLVM19 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

1. 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

2. Overview Assembly LLVM IR (x86-64, ARM, ..) [0, 2 64 ) [0, 2 64 ) + provenance Pointer [0, 2 64 ) [0, 2 64 ) + ? Integer 2

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

4. 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

5. 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

6. 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

7. 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

8. 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

9. 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

10. 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

11. 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

12. 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

13. 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

14. 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

15. 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

16. 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

17. 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

18. 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

19. 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

20. 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

21. 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

22. 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

23. 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

24. 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

25. 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

26. 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

27. 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