# ERACE: Toward Facilitating Exploit Generation for Kernel Race Vulnerabilities
## 3 Motivating Example and Overview  
### Motivating Example  
Figure 2 shows a PoC program in the C coding language that can trigger the kernel race vulnerability CVE-2016-8655. setstockopt() in line 3 and line 9 is a system call that can operate on the socket created in line 15. If the operation option in line 3 is PACKET_RX_RING, the kernel will call packet_set_ring() to set the ring buffer. If the operation option in line 9 is PACKET_VERSION, the kernel will call packet_setsockopt() to modify the packet version. Both functions access the value tp_version, which may cause a competing conflict. In line 21 and line 22, the PoC creates two threads. These two threads will make kernel call packet_set_ring() and packet_setsockopt(), respectively. Calling these two threads in an infinite loop may lead to race conditions and trigger the vulnerability. The triggering principle is shown in Figure 3. Normally, when the packet_set_ring() creates a ring buffer, if the packet version is PACKET_V3, it will call init_prb_bdqc() to initialize the timer. When the packet version is greater than PACKET_V2, the kernel will call prb_shutdown_retire_blk_timer() to release and delete the previously initialized timer. If another thread modifies the packet version in the middle of the call, although the socket will call kfree() to release the previously initialized timer when the close() is executed at the end, the timer is not deregistered in the kernel queue. When the timer expires, the callback in the timer is called, triggering a UAF issue. In this vulnerability, the race point is the instruction, where the variable po->tp_version is marked in red in Figure 3. Thread A reads tp_version twice (V1 and V2) and thread B writes tp_version once (V3). When we tested the kernel (Linux kernel version 4.12.1) compiled with KASAN, the vulnerability point reported by KASAN is in the kernel's run_timer_softirq(). Actually, this is the triggering point, not the race point. There is no output information about the stack traceback at the race point. Researchers still need to spend a lot of time auditing the source code so it is difficult to locate the vulnerability point simply from the KASAN report. In addition, there is no other tool that is more helpful for locating race points. The triggering type of this vulnerability is a UAF. According to our observations, KASAN sometimes reports the vulnerability type as a UAF and sometimes reports it as a null dereference. The KASAN report is not accurate enough. Many vulnerability types, such as the OOB write and double-free types, can also trigger null dereferences so inaccurate reports will increase the difficulty of the exploitation. In our experiments, we compare the accuracy of ERACE and KASAN in recognizing triggering types. Moreover, the information provided by KASAN is very limited and we can neither evaluate the exploitability nor choose an appropriate exploitation method. For the triggering types, in addition to the UAF, there are also the OOB write, double-free, and direct CFH types. Different triggering types have different exploitation methods, which we introduce in detail in Section 4. Figure 2: A PoC code fragment of kernel race vulnerability, CVE-2016-8655. The checkpoint of this vulnerability can be seen in Figure 4. Confirming whether the race condition is satisfied is equivalent to confirming whether V3 is executed between V1 and V2. Since the vulnerable code is located in the kernel space, we can only craft user-space programs to confirm this. If we want the kernel to successfully execute V3, we must bypass the condition at point P2, otherwise, it will return directly. The statement at P3 will set pg_vec to 1, making the condition of P2 unable to be bypassed so P2 must be executed before P3. As long as V3 can modify tp_version, it means that P2 was executed before P3. Then, because the time window between P2 and V3 is smaller than the time window between P3 and V2, it is more likely that V3 is executed before V2.