efficient cfi enforcement for c dynamic dispatch
play

Efficient CFI Enforcement for C++ Dynamic Dispatch Dimitar Bounov , - PowerPoint PPT Presentation

Efficient CFI Enforcement for C++ Dynamic Dispatch Dimitar Bounov , Rami Kici, Sorin Lerner UCSD Why A:ack Dynamic Dispatch? Valuable targets (e.g. browsers) 11M LOC ~30M LOC 7M LOC ?M LOC C/C++ C/C++ C/C++ C/C++ Why A:ack Dynamic


  1. Efficient CFI Enforcement for C++ Dynamic Dispatch Dimitar Bounov , Rami Kici, Sorin Lerner UCSD

  2. Why A:ack Dynamic Dispatch? • Valuable targets (e.g. browsers) 11M LOC ~30M LOC 7M LOC ?M LOC C/C++ C/C++ C/C++ C/C++

  3. Why A:ack Dynamic Dispatch? • Valuable targets (e.g. browsers) • Prevalence of Dynamic Dispatch • 91.8 % of Indirect Calls in Chrome [ Tice ’14 ]

  4. Why A:ack Dynamic Dispatch? • Valuable targets (e.g. browsers) • Prevalence of Dynamic Dispatch • Exploited in the wild

  5. Prior Work and ContribuAon • Prior defenses vfGuard [Prakash’15], VTInt [Zhao’15], SafeDispatch [Jang’14], VTV [Tice’14] ... • Our contribu^on: novel VTable layouts • Lower overhead & no profiling

  6. Example class A { A Afoo() virtual void foo(); } class B : public A { Bfoo() Afoo() B C virtual void foo(); Bbar() Cbaz() virtual void bar(); } class C : public A { D Dfoo() virtual void baz(); Bbar() } Dboo() class D : public B { virtual void foo(); virtual void boo(); }

  7. C++ Memory Layout A Afoo() Bfoo() Afoo() B C Bbar() Cbaz() D Dfoo() Bbar() Dboo()

  8. C++ Memory Layout Object Instance Virtual Table C A A Afoo() Afoo … … Bfoo Bbar Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Cbaz … … Dfoo D Dfoo() Bbar Bbar() Dboo() Dboo

  9. Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Bbar Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Cbaz … … Dfoo D Dfoo() Bbar Bbar() Dboo() Dboo vptr = (*a) A* a = (A*) … fn_ptr = (*(vptr + 0)) a->foo() (*fn_ptr)(); Method Index

  10. ExploiAng Dynamic Dispatch exec C A A Afoo() Afoo … … Bfoo Bbar Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Cbaz … … Dfoo D Dfoo() Bbar Bbar() Dboo() Dboo vptr = (*a) fn_ptr = (*(vptr + 0)) (*fn_ptr)();

  11. ProtecAng Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Bbar Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Cbaz … … Dfoo D Dfoo() Bbar Bbar() Dboo() Dboo vptr = (*a) fn_ptr = (*(vptr + 0)) (*fn_ptr)();

  12. ProtecAng Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Bbar Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Cbaz … … Dfoo D Dfoo() Bbar Bbar() Dboo() Dboo vptr = (*a) assert (vptr ∈ { A, B, C, D }) fn_ptr = (*(vptr + 0)) (*fn_ptr)();

  13. ProtecAng Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Bbar Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Cbaz … … Dfoo D Dfoo() Bbar Bbar() Dboo() Dboo Read-Only vptr = (*a) assert (vptr ∈ { A, B, C, D }) fn_ptr = (*(vptr + 0)) (*fn_ptr)(); Inline Constant

  14. ProtecAng Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Bbar Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Cbaz … … Dfoo D Dfoo() Bbar Bbar() Dboo() Dboo vptr = (*a) assert (vptr ∈ { A, B, C, D }) How to implement safety fn_ptr = (*(vptr + 0)) check efficiently? (*fn_ptr)();

  15. ProtecAng Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Bbar Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Cbaz … … Dfoo D Dfoo() Bbar Bbar() Dboo() Dboo vptr = (*a) Non-regular values assert (vptr ∈ { 0x0, 0x8, 0x18, 0x28 }) fn_ptr = (*(vptr + 0)) Hard to test (*fn_ptr)();

  16. ProtecAng Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Key idea 1: Bbar Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Cbaz Order and Pad VTables … … Dfoo D Dfoo() Bbar Bbar() Dboo() Dboo vptr = (*a) Non-regular values assert (vptr ∈ { 0x0, 0x8, 0x18, 0x28 }) fn_ptr = (*(vptr + 0)) Hard to test (*fn_ptr)();

  17. Ordered Memory Layout Afoo C A A 24 B Afoo() … … Bfoo Bbar Bfoo() Afoo() B C 16 B Bbar() Cbaz() B D Dfoo … … Bbar D Dfoo() Dboo Bbar() 8 B Dboo() Afoo Cbaz 1. Traverse in pre-order: A, B, D, C 2. For each class layout vtable and pad

  18. Ordered Memory Layout Afoo C A A 24 B Afoo() … … Bfoo Bbar Bfoo() Afoo() B C 16 B Bbar() Cbaz() B D Dfoo … … Bbar D Dfoo() Dboo Bbar() 8 B Dboo() Afoo vptr = (*a) Cbaz 1. Traverse in pre-order: A, B, D, C assert (vptr ∈ { A,B,C,D }) fn_ptr = (*(vptr + 0)) 2. For each class layout vtable and pad (*fn_ptr)();

  19. Ordered Memory Layout Afoo C A A 24 B Afoo() … … Bfoo Bbar Bfoo() Afoo() B C 16 B Bbar() Cbaz() B D Dfoo … … Bbar D Dfoo() Dboo Bbar() 8 B Dboo() Afoo vptr = (*a) Cbaz assert (vptr ∈ { A,B,C,D }) fn_ptr = (*(vptr + 0)) (*fn_ptr)();

  20. Ordered Memory Layout Afoo C A A 24 B Afoo() … … Bfoo Bbar Bfoo() Afoo() B C 16 B Bbar() Cbaz() B D Dfoo … … Bbar D Dfoo() Dboo Bbar() 8 B Dboo() Afoo vptr = (*a) Cbaz assert (vptr ∈ { 0x0, 0x20, 0x40, 0x60 }) Regular fn_ptr = (*(vptr + 0)) (*fn_ptr)(); Address Points

  21. Ordered Memory Layout Afoo C A A 24 B Afoo() … … Bfoo Bbar Bfoo() Afoo() B C 16 B Bbar() Cbaz() B D Dfoo … … Bbar D Dfoo() Dboo Bbar() 8 B Dboo() Afoo vptr = (*a) Cbaz assert (vptr ∈ { 0x0, 0x20, 0x40, 0x60 }) fn_ptr = (*(vptr + 0)) (*fn_ptr)(); Efficient Check

  22. Ordered Memory Layout Afoo C A A 24 B Afoo() … … Bfoo Bbar Bfoo() Afoo() B C 16 B Bbar() Cbaz() B D Dfoo … … Bbar D Dfoo() Dboo Bbar() 8 B Dboo() Afoo vptr = (*a) Cbaz assert (0x0 ≤ vptr ≤ 0x60 ∧ vptr % 0x20 = 0) fn_ptr = (*(vptr + 0)) (*fn_ptr)(); Efficient Check

  23. Ordered Memory Layout Afoo C A A 24 B Afoo() … … Bfoo Bbar Bfoo() Afoo() B C 16 B Bbar() Cbaz() B D Dfoo … … Bbar D Dfoo() Dboo Bbar() 8 B Dboo() Afoo vptr = (*b) Cbaz assert (vptr ∈ { B, D }) fn_ptr = (*(vptr + 0)) (*fn_ptr)();

  24. Ordered Memory Layout Afoo C A A 24 B Afoo() … … Bfoo Bbar Bfoo() Afoo() B C 16 B Bbar() Cbaz() B D Dfoo … … Bbar D Dfoo() Dboo Bbar() 8 B Dboo() Afoo vptr = (*b) Cbaz assert (vptr ∈ { 0x20, 0x40 }) fn_ptr = (*(vptr + 0)) (*fn_ptr)();

  25. Ordered Memory Layout Afoo C A A 24 B Afoo() … … Bfoo Bbar Bfoo() Afoo() B C 16 B Bbar() Cbaz() B D Dfoo … … Bbar D Dfoo() Dboo Bbar() 8 B Dboo() Afoo vptr = (*b) Cbaz assert (0x20 ≤ vptr ≤ 0x40 ∧ vptr % 0x20 = 0) fn_ptr = (*(vptr + 0)) (*fn_ptr)();

  26. Ordered Memory Layout Afoo C A A 24 B Afoo() … … Bfoo Bbar Bfoo() Afoo() B C 16 B Bbar() Cbaz() B D Dfoo … … Bbar D Dfoo() Dboo Bbar() 8 B Dboo() Afoo Cbaz Wasteful Extra Padding

  27. Ordered Memory Layout Afoo C A A 24 B Afoo() … … Bfoo Bbar Key idea 2: Bfoo() Afoo() B C 16 B Bbar() Cbaz() B D Dfoo Interleave VTables … … Bbar D Dfoo() Dboo Bbar() 16 B Dboo() Afoo Cbaz Wasteful Extra Padding

  28. Interleaved Memory Layout C A A Afoo() … … Bfoo() Afoo() B C Bbar() Cbaz() B D … … D Dfoo() Bbar() Dboo() 1. Traverse in pre-order: A, B, D, C 2. Layout each method

  29. Interleaved Memory Layout C A A Afoo() Afoo … … Bfoo Dfoo Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Bbar … … Bbar D Dfoo() Dboo Bbar() Dboo() Cbaz 1. Traverse in pre-order: A, B, D, C 2. Layout each method

  30. Interleaved Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Dfoo Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Bbar … … Bbar D Dfoo() Dboo Bbar() Dboo() Cbaz vptr = (*a) 1. Traverse in pre-order: A, B, D, C assert (vptr ∈ { A,B,C,D }) fn_ptr = (*(vptr + 0)) 2. Layout each method (*fn_ptr)();

  31. Interleaved Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Dfoo Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Bbar … … Bbar D Dfoo() Dboo Bbar() Dboo() Cbaz vptr = (*a) assert (vptr ∈ { A,B,C,D }) fn_ptr = (*(vptr + 0)) (*fn_ptr)();

  32. Interleaved Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Dfoo Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Bbar … … Bbar D Dfoo() Dboo Bbar() Dboo() Cbaz vptr = (*a) assert (vptr ∈ { 0x0, 0x8, 0x10, 0x18 }) Address Points fn_ptr = (*(vptr + 0)) (*fn_ptr)(); Consecu^ve Addrs.

  33. Interleaved Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Dfoo Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Bbar … … Bbar D Dfoo() Dboo Bbar() Dboo() Cbaz vptr = (*a) assert (0x0 ≤ vptr ≤ 0x18 ∧ vptr % 0x8 = 0) fn_ptr = (*(vptr + 0)) Same Check (*fn_ptr)(); Different range & alignment

  34. Interleaved Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Dfoo Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Bbar … … Bbar D Dfoo() Dboo Bbar() Dboo() Cbaz vptr = (*b) assert (0x0 ≤ vptr ≤ 0x18 ∧ vptr % 0x8 = 0) fn_ptr = (*(vptr + 0)) (*fn_ptr)();

  35. Interleaved Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Dfoo Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Bbar … … Bbar D Dfoo() Dboo Bbar() Dboo() Cbaz vptr = (*b) assert (0x8 ≤ vptr ≤ 0x10 ∧ vptr % 0x8 = 0) fn_ptr = (*(vptr + 0)) (*fn_ptr)();

  36. Interleaved Dynamic Dispatch C A A Afoo() Afoo … … Bfoo Dfoo Bfoo() Afoo() B C Bbar() Cbaz() Afoo B D Bbar … … Bbar D Dfoo() Dboo Bbar() Dboo() Cbaz vptr = (*b) assert (0x8 ≤ vptr ≤ 0x10 ∧ vptr % 0x8 = 0) fn_ptr = (*(vptr + 0)) (*fn_ptr)();

Recommend


More recommend