through fuzzing
play

through Fuzzing Dae R. Jeong Kyungtae Kim Basavesh Shivakumar - PowerPoint PPT Presentation

Razzer: Finding Kernel Race Bugs through Fuzzing Dae R. Jeong Kyungtae Kim Basavesh Shivakumar Byoungyoung Lee Insik Shin Korea Advanced Institute of Science and Technology Seoul National University Purdue


  1. Razzer: Finding Kernel Race Bugs through Fuzzing Dae R. Jeong † Kyungtae Kim ∗ Basavesh Shivakumar ∗ Byoungyoung Lee ‡ ∗ Insik Shin † † Korea Advanced Institute of Science and Technology ‡ Seoul National University ∗ Purdue University

  2. Kernel Vulnerability 2

  3. Kernel Vulnerability 2

  4. Kernel Vulnerability Attacker can control the entire system 2

  5. Fuzzing: Focused to Extend Coverage • Fuzzing • One of the most practical approaches in finding vulnerabilities • Coverage-guided fuzzing • It gathers interesting inputs that extend code coverage. • The more coverage, the more vulnerabilities 3

  6. Race Bugs • Assumption: Race condition between two threads • Race condition occurs if following three conditions meet • Two instructions access the same memory location • At least one of two is a write instruction • These two are executed concurrently • If a race occurs, the computational results may vary depending on the execution order • A race vulnerability is caused by the execution order unintended by developers. 4

  7. Inefficient Fuzzing for Race Bugs • Traditional fuzzers are inefficient to find race bugs • Instructions should be executed within a specific time window • Called as race window • Execution orders are not determined by the fuzzer • Execution orders are determined by the kernel scheduler 5

  8. Inefficient Fuzzing for Race Bugs: Example Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window strcpy(buf, file_name ); 6

  9. Inefficient Fuzzing for Race Bugs: Example Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window strcpy(buf, file_name ); 6

  10. Inefficient Fuzzing for Race Bugs: Example Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window strcpy(buf, file_name ); 6

  11. Inefficient Fuzzing for Race Bugs: Example Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window strcpy(buf, file_name ); 6

  12. Inefficient Fuzzing for Race Bugs: Example Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window file_name is longer than strcpy(buf, file_name ); the allocated buffer 6

  13. Inefficient Fuzzing for Race Bugs: Example Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window file_name is longer than strcpy(buf, file_name ); the allocated buffer Buffer overflow! 6

  14. Inefficient Fuzzing for Race Bugs: Syzkaller • Syzkaller • A kernel syscall fuzzer developed by Google • Run Syzkaller to find three race bugs with limited set of syscalls • CVE-2016-8655 • CVE-2017-17712 • CVE-2017-2636 • None of CVEs was found within 10 hours • Traditional fuzzing is inefficient to find race bugs • Razzer can find all of them within 7~30 minutes 7

  15. Our approach: Razzer Thread interleaving Code coverage len = strlen( file_name ); buf = kmalloc(len); strcpy( file_name , longer_name); strcpy(buf, file_name ); 8

  16. Our approach: Razzer Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window strcpy(buf, file_name ); 9

  17. Our approach: Razzer Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window BP strcpy(buf, file_name ); BP 9

  18. Our approach: Razzer Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window BP strcpy(buf, file_name ); BP 9

  19. Our approach: Razzer Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window strcpy(buf, file_name ); BP 9

  20. Our approach: Razzer Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window strcpy(buf, file_name ); 9

  21. Our approach: Razzer Thread 1 Thread 2 Syscall: open() Syscall: rename() len = strlen( file_name ); buf = kmalloc(len); Race strcpy( file_name , longer_name); window strcpy(buf, file_name ); Buffer overflow! 9

  22. Design Overview Offline Online analysis testing Over-approximated Multi-thread Source data races input code Static analysis Single-thread Multi-thread fuzzing fuzzing 10

  23. Design Overview Offline Online analysis testing Over-approximated Multi-thread Source data races input code Static analysis Single-thread Multi-thread fuzzing fuzzing 11

  24. Static Analysis • Identifying instructions that may race • Teaching Razzer where to install breakpoints to trigger race • Inclusion-based points-to analysis • Also known as Andersen-style points-to analysis • This static analysis certainly has false positives • Next phases (fuzzing) takes care of this issue because it is “fuzzing” 12

  25. Static Analysis: Example Source code Read len = strlen( file_name ); buf = kmalloc(len); Write strcpy( file_name , longer_name); Read strcpy(buf, file_name ); 13

  26. Static Analysis: Example Source code Razzer identified 3.4M race candidates over the entire Linux kernel Read len = strlen( file_name ); buf = kmalloc(len); Write strcpy( file_name , longer_name); Read strcpy(buf, file_name ); 13

  27. Design Overview Offline Online analysis testing Over-approximated Multi-thread Source data races input code Static analysis Single-thread Multi-thread fuzzing fuzzing 14

  28. Single-thread Fuzzing Single-thread input … open() rename() … 15

  29. Single-thread Fuzzing Thread 1 Single-thread Syscall: open() input len = strlen( file_name ); … buf = kmalloc(len); open() strcpy(buf, file_name ); rename() … Syscall: rename() strcpy( file_name , longer_name); 15

  30. Transformation to Multi-thread Input … open() rename() … 16

  31. Transformation to Multi-thread Input Thread 2 Thread 1 … open() rename() … 16

  32. Transformation to Multi-thread Input Thread 2 Thread 1 … len = strlen( file_name ); buf = kmalloc(len); open() strcpy( file_name , BP rename() longer_name); strcpy(buf, file_name ); BP … 16

  33. Design Overview Offline Online analysis testing Over-approximated Multi-thread Source data races input code Static analysis Single-thread Multi-thread fuzzing fuzzing 17

  34. Multi-thread Fuzzing CPU 2 CPU 1 Thread 1 Thread 2 len = strlen( file_name ); … buf = kmalloc(len); strcpy( file_name , BP Syscall n Syscall m longer_name); strcpy(buf, file_name ); BP … Guest VM 18

  35. Multi-thread Fuzzing CPU 2 CPU 1 Thread 1 Thread 2 len = strlen( file_name ); … buf = kmalloc(len); strcpy( file_name , BP Syscall n Syscall m longer_name); strcpy(buf, file_name ); BP … Guest VM Hypervisor Thread 2 Thread 1 18

  36. Multi-thread Fuzzing CPU 2 CPU 1 Thread 1 Thread 2 len = strlen( file_name ); … buf = kmalloc(len); Hypercall Hypercall strcpy( file_name , BP Syscall n Syscall m longer_name); strcpy(buf, file_name ); BP … Guest VM Hypervisor Thread 2 Thread 1 18

  37. Multi-thread Fuzzing CPU 2 CPU 1 Thread 1 Thread 2 len = strlen( file_name ); … buf = kmalloc(len); Hypercall Hypercall strcpy( file_name , BP Syscall n Syscall m longer_name); strcpy(buf, file_name ); BP … Guest VM Hypervisor Thread 2 Thread 1 18

  38. Multi-thread Fuzzing CPU 2 CPU 1 Thread 1 Thread 2 len = strlen( file_name ); … buf = kmalloc(len); Hypercall Hypercall strcpy( file_name , BP Syscall n Syscall m longer_name); strcpy(buf, file_name ); BP … Guest VM Hypervisor strcpy( file_name , other_name); strcpy(buf, file_name ); Thread 2 Thread 1 18

  39. Multi-thread Fuzzing CPU 2 CPU 1 Thread 1 Thread 2 len = strlen( file_name ); … buf = kmalloc(len); Hypercall Hypercall strcpy( file_name , BP Syscall n Syscall m longer_name); strcpy(buf, file_name ); BP … Guest VM Hypervisor strcpy( file_name , other_name); strcpy(buf, file_name ); Two threads access the same memory  A race condition is occurred Thread 2 Thread 1 18

  40. Implementation • Static analysis • Implemented using SVF which is based on LLVM compiler suite • Single-thread/Multi-thread fuzzing • Implemented based on Syzkaller • Deterministic scheduler • Implemented using QEMU/KVM • Exposing hypercall interfaces to support per-core breakpoint 19

  41. Evaluation • 30 new races in the Linux kernel • 15 were fixed

  42. Evaluation • 30 new races in the Linux kernel • 15 were fixed Use-after-free

  43. Evaluation • 30 new races in the Linux kernel • 15 were fixed Use-after-free Heap overflow

  44. Evaluation • 30 new races in the Linux kernel • 15 were fixed Use-after-free Heap overflow Double free

Recommend


More recommend