safely optimizing casts between
play

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