reconciling high level optimizations and
play

Reconciling High-Level Optimizations and Low-Level Code in LLVM - PowerPoint PPT Presentation

OOPSLA 18 Boston Reconciling High-Level Optimizations and Low-Level Code in LLVM 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. Miscompilation with Int-Ptr Casting 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

  2. Miscompilation with Int-Ptr Casting 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

  3. Miscompilation with Int-Ptr Casting 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

  4. Miscompilation with Int-Ptr Casting 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) { *(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; print(q[0]); print(0); } } 7

  5. Miscompilation with Int-Ptr Casting 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) { *(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; constant print(q[0]); print(0); } prop. } 7

  6. Miscompilation with Int-Ptr Casting 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) { *(char*)(int)(p+1)=10; *(char*)iq = 10; print(q[0]); print(q[0]); 10 } } 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

  7. Miscompilation with Int-Ptr Casting 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) { *(char*)(int)(p+1)=10; *(char*)iq = 10; print(q[0]); print(q[0]); 10 } } 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

  8. Miscompilation with Int-Ptr Casting 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) { *(char*)(int)(p+1)=10; *(char*)iq = 10; print(q[0]); print(q[0]); 10 } } 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

  9. Miscompilation with Int-Ptr Casting char p[1],q[1]={0}; char p[1],q[1]={0}; We found this miscompilation bug int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; in both LLVM & GCC if (iq == ip) { if (iq == ip) { *(char*)(int)(p+1)=10; *(char*)iq = 10; print(q[0]); print(q[0]); 10 } } 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

  10. Miscompilation with Int-Ptr Casting char p[1],q[1]={0}; char p[1],q[1]={0}; We found this miscompilation bug int ip = (int)(p+1); int ip = (int)(p+1); int iq = (int)q; int iq = (int)q; in both LLVM & GCC if (iq == ip) { if (iq == ip) { *(char*)(int)(p+1)=10; *(char*)iq = 10; print(q[0]); print(q[0]); Goal of this paper 10 } } Finding a good memory model for char p[1],q[1] = {0}; char p[1],q[1] = {0}; pointer ↔ integer casting 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

  11. Problems & Our Solutions 8

  12. Problem 1 9

  13. Pointer → Integer Casting? (int)p 10

  14. Pointer → Integer Casting? (p,0x100) (int)p 10

  15. Pointer → Integer Casting? (p,0x100) (int)p 10

  16. Pointer → Integer Casting? (p,0x100) (int)p (p,0x100) 1. Carry Provenance 10

  17. Pointer → Integer Casting? (p,0x100) (int)p (p,0x100) 0x100 2. Drop 1. Carry Provenance Provenance 10

  18. Pointer → Integer Casting? (p,0x100) (int)p (p,0x100) 0x100 2. Drop 1. Carry Provenance Provenance 10

  19. Pointer → Integer Casting? (p,0x100) (int)p (p,0x100) 0x100 1. Carry 2. Drop Provenance Provenance 10

  20. Carry Provenance: Integer Optimization Problem 1. Carry Provenance k = (i==j ? i : j) k = j 11

  21. Carry Provenance: Integer Optimization Problem 1. Carry Provenance k = (i==j ? i : j) k = j true 11

  22. Carry Provenance: Integer Optimization Problem 1. Carry Provenance k = (i==j ? i : j) k = j true i 11

  23. Carry Provenance: Integer Optimization Problem 1. Carry Provenance k = (i==j ? i : j) k = j true j 11

  24. Carry Provenance: Integer Optimization Problem 1. Carry Provenance k = (i==j ? i : j) k = j false 11

  25. Carry Provenance: Integer Optimization Problem 1. Carry Provenance k = (i==j ? i : j) k = j false j 11

  26. Carry Provenance: Integer Optimization Problem 1. Carry Provenance k = (i==j ? i : j) k = j j 11

  27. Carry Provenance: Integer Optimization Problem 1. Carry Provenance (p,0x100) k = (i==j ? i : j) k = j 11

  28. Carry Provenance: Integer Optimization Problem 1. Carry Provenance (p,0x100) k = (i==j ? i : j) k = j (q,0x100) 11

  29. Carry Provenance: Integer Optimization Problem 1. Carry Provenance (p,0x100) k = (i==j ? i : j) k = j true (q,0x100) 11

  30. Carry Provenance: Integer Optimization Problem 1. Carry Provenance (p,0x100) k = (i==j ? i : j) k = j true (q,0x100) 11

  31. Carry Provenance: Integer Optimization Problem 1. Carry Provenance (p,0x100) k = (i==j ? i : j) k = j true (q,0x100) (q,0x100) 11

  32. Carry Provenance: Integer Optimization Problem Problem 1. Carry Provenance Integer optimizations may change provenance (p,0x100) k = (i==j ? i : j) k = j true (q,0x100) (q,0x100) 11

  33. Carry Provenance: Integer Optimization Problem 2. Drop Provenance (p,0x100) k = (i==j ? i : j) k = j true (q,0x100) (q,0x100) 12

  34. Carry Provenance: Integer Optimization Problem 2. Drop Provenance (p,0x100) 0x100 k = (i==j ? i : j) k = j true (q,0x100) 0x100 (q,0x100) 0x100 12

  35. Problem 2 13

  36. Integer → Pointer Casting? char p[1] Memory: 0x100 (int*)0x100 14

  37. Integer → Pointer Casting? char p[1] Memory: 0x100 (int*)0x100 ( Ø ,0x100) 1. Always Empty 14

  38. Integer → Pointer Casting? char p[1] Memory: 0x100 (int*)0x100 ( Ø ,0x100) 2. Depending on 1. Always Empty the Memory Layout 14

  39. Integer → Pointer Casting? Memory: 0x100 (int*)0x100 ( Ø ,0x100) ( Ø ,0x100) 2. Depending on 1. Always Empty the Memory Layout 14

  40. Integer → Pointer Casting? char p[1] Memory: 0x100 (int*)0x100 ( Ø ,0x100) (p,0x100) 2. Depending on 1. Always Empty the Memory Layout 14

  41. Integer → Pointer Casting? char p[1] Memory: 0x100 (int*)0x100 ( Ø ,0x100) ( ∗ ,0x100) (p,0x100) 2. Depending on 1. Always Empty 3. Always Full the Memory Layout 14

  42. Integer → Pointer Casting? char p[1] Memory: 0x100 (int*)0x100 ( Ø ,0x100) ( ∗ ,0x100) (p,0x100) 2. Depending on 1. Always Empty 3. Always Full the Memory Layout 14

  43. Integer → Pointer Casting? char p[1] Memory: 0x100 (int*)0x100 ( Ø ,0x100) ( ∗ ,0x100) (p,0x100) 2. Depending on 1. Always Empty 3. Always Full the Memory Layout 14

  44. Empty Provenance: Pointer – Integer Round Trip 1. Always Empty char p[1] Memory: 0x100 i = (int)p p2 = (char*)i *p2 = 10 15

  45. Empty Provenance: Pointer – Integer Round Trip 1. Always Empty char p[1] Memory: 0x100 (p,0x100) i = (int)p p2 = (char*)i *p2 = 10 15

  46. Empty Provenance: Pointer – Integer Round Trip 1. Always Empty char p[1] Memory: 0x100 0x100 (p,0x100) i = (int)p p2 = (char*)i *p2 = 10 15

  47. Empty Provenance: Pointer – Integer Round Trip 1. Always Empty char p[1] Memory: 0x100 0x100 (p,0x100) i = (int)p p2 = (char*)i ( ∅ ,0x100) *p2 = 10 15

  48. Empty Provenance: Pointer – Integer Round Trip 1. Always Empty char p[1] Memory: 0x100 0x100 (p,0x100) i = (int)p p2 = (char*)i ( ∅ ,0x100) *p2 = 10 UB 15

  49. Empty Provenance: Pointer – Integer Round Trip Problem 1. Always Empty Common program patterns raise UB char p[1] Memory: 0x100 0x100 (p,0x100) i = (int)p p2 = (char*)i ( ∅ ,0x100) *p2 = 10 UB 15

  50. Empty Provenance: Pointer – Integer Round Trip 3. Always Full char p[1] Memory: 0x100 0x100 (p,0x100) i = (int)p p2 = (char*)i ( ∅ ,0x100) *p2 = 10 UB 16

  51. Empty Provenance: Pointer – Integer Round Trip 3. Always Full char p[1] Memory: 0x100 0x100 (p,0x100) i = (int)p p2 = (char*)i ( ∅ ,0x100) ( ∗ ,0x100) *p2 = 10 UB 16

  52. Empty Provenance: Pointer – Integer Round Trip 3. Always Full char p[1] 10 Memory: 0x100 0x100 (p,0x100) i = (int)p p2 = (char*)i ( ∅ ,0x100) ( ∗ ,0x100) *p2 = 10 16

  53. Integer → Pointer Casting? char p[1] Memory: 0x100 (int*)0x100 ( Ø ,0x100) ( ∗ ,0x100) (p,0x100) (p,0x100) 2. Depending on 1. Always Empty 3. Always Full the Memory Layout 17

  54. Integer → Pointer Casting? char p[1] Memory: 0x100 (int*)0x100 ( Ø ,0x100) ( ∗ ,0x100) (p,0x100) (p,0x100) 2. Depending on 1. Always Empty 3. Always Full the Memory Layout 17

  55. Depending on the Memory Layout: Reordering 2. Depending on the Memory Layout char p[1] Memory: 0x100 q = (int*)0x100 char *p = malloc(1) char *p = malloc(1) q = (int*)0x100 18

  56. Depending on the Memory Layout: Reordering 2. Depending on the Memory Layout char p[1] Memory: 0x100 q = (int*)0x100 char *p = malloc(1) char *p = malloc(1) q = (int*)0x100 18

  57. Depending on the Memory Layout: Reordering 2. Depending on the Memory Layout char p[1] Memory: 0x100 q = (int*)0x100 char *p = malloc(1) char *p = malloc(1) q = (int*)0x100 (p,0x100) 18

  58. Depending on the Memory Layout: Reordering 2. Depending on the Memory Layout Memory: 0x100 q = (int*)0x100 char *p = malloc(1) char *p = malloc(1) q = (int*)0x100 (p,0x100) 18

  59. Depending on the Memory Layout: Reordering 2. Depending on the Memory Layout Memory: 0x100 ( Ø ,0x100) q = (int*)0x100 char *p = malloc(1) char *p = malloc(1) q = (int*)0x100 (p,0x100) 18

  60. Depending on the Memory Layout: Reordering 2. Depending on the Memory Layout Memory: Problem 0x100 ( Ø ,0x100) Movement of casts, or functions including them, is restricted q = (int*)0x100 char *p = malloc(1) char *p = malloc(1) q = (int*)0x100 (p,0x100) 18

  61. Depending on the Memory Layout: Reordering 3. Always Full char p[1] Memory: 0x100 ( Ø ,0x100) q = (int*)0x100 char *p = malloc(1) char *p = malloc(1) q = (int*)0x100 (p,0x100) 19

  62. Depending on the Memory Layout: Reordering 3. Always Full char p[1] Memory: 0x100 ( Ø ,0x100) ( ∗ ,0x100) q = (int*)0x100 char *p = malloc(1) char *p = malloc(1) q = (int*)0x100 ( ∗ ,0x100) (p,0x100) 19

  63. Problem 3 20

  64. Problems with Full Provenance Anyone can modify other’s local variables by 1. Guessing their addresses & 2. Acquiring full provenance via casting char p[1] = {0}; f(); print(p[0]); 21

  65. Problems with Full Provenance Anyone can modify other’s local variables by 1. Guessing their addresses & 2. Acquiring full provenance via casting char p[1] = {0}; char p[1] = {0}; f(); f(); print(p[0]); print(0); constant prop. 21

  66. Problems with Full Provenance Anyone can modify other’s local variables by 1. Guessing their addresses & 2. Acquiring full provenance via casting (p,0x100) char p[1] = {0}; char p[1] = {0}; f(); f(); print(p[0]); print(0); constant prop. 21

  67. Problems with Full Provenance Anyone can modify other’s local variables by 1. Guessing their addresses & 2. Acquiring full provenance via casting (p,0x100) char p[1] = {0}; char p[1] = {0}; f(); f(); *(char*)(0x100)=1; print(p[0]); print(0); constant prop. 21

  68. Problems with Full Provenance Anyone can modify other’s local variables by 1. Guessing their addresses & 2. Acquiring full provenance via casting (p,0x100) ( ∗ ,0x100) char p[1] = {0}; char p[1] = {0}; f(); f(); *(char*)(0x100)=1; print(p[0]); print(0); constant Full Provenance prop. 21

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend