]>
Commit | Line | Data |
---|---|---|
53bc0d35 GKH |
1 | From 0803278b0b4d8eeb2b461fb698785df65a725d9e Mon Sep 17 00:00:00 2001 |
2 | From: Xu Yu <xuyu@linux.alibaba.com> | |
3 | Date: Thu, 21 Mar 2019 18:00:35 +0800 | |
4 | Subject: bpf: do not restore dst_reg when cur_state is freed | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | From: Xu Yu <xuyu@linux.alibaba.com> | |
10 | ||
11 | commit 0803278b0b4d8eeb2b461fb698785df65a725d9e upstream. | |
12 | ||
13 | Syzkaller hit 'KASAN: use-after-free Write in sanitize_ptr_alu' bug. | |
14 | ||
15 | Call trace: | |
16 | ||
17 | dump_stack+0xbf/0x12e | |
18 | print_address_description+0x6a/0x280 | |
19 | kasan_report+0x237/0x360 | |
20 | sanitize_ptr_alu+0x85a/0x8d0 | |
21 | adjust_ptr_min_max_vals+0x8f2/0x1ca0 | |
22 | adjust_reg_min_max_vals+0x8ed/0x22e0 | |
23 | do_check+0x1ca6/0x5d00 | |
24 | bpf_check+0x9ca/0x2570 | |
25 | bpf_prog_load+0xc91/0x1030 | |
26 | __se_sys_bpf+0x61e/0x1f00 | |
27 | do_syscall_64+0xc8/0x550 | |
28 | entry_SYSCALL_64_after_hwframe+0x49/0xbe | |
29 | ||
30 | Fault injection trace: | |
31 | ||
32 | kfree+0xea/0x290 | |
33 | free_func_state+0x4a/0x60 | |
34 | free_verifier_state+0x61/0xe0 | |
35 | push_stack+0x216/0x2f0 <- inject failslab | |
36 | sanitize_ptr_alu+0x2b1/0x8d0 | |
37 | adjust_ptr_min_max_vals+0x8f2/0x1ca0 | |
38 | adjust_reg_min_max_vals+0x8ed/0x22e0 | |
39 | do_check+0x1ca6/0x5d00 | |
40 | bpf_check+0x9ca/0x2570 | |
41 | bpf_prog_load+0xc91/0x1030 | |
42 | __se_sys_bpf+0x61e/0x1f00 | |
43 | do_syscall_64+0xc8/0x550 | |
44 | entry_SYSCALL_64_after_hwframe+0x49/0xbe | |
45 | ||
46 | When kzalloc() fails in push_stack(), free_verifier_state() will free | |
47 | current verifier state. As push_stack() returns, dst_reg was restored | |
48 | if ptr_is_dst_reg is false. However, as member of the cur_state, | |
49 | dst_reg is also freed, and error occurs when dereferencing dst_reg. | |
50 | Simply fix it by testing ret of push_stack() before restoring dst_reg. | |
51 | ||
52 | Fixes: 979d63d50c0c ("bpf: prevent out of bounds speculation on pointer arithmetic") | |
53 | Signed-off-by: Xu Yu <xuyu@linux.alibaba.com> | |
54 | Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> | |
55 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
56 | ||
57 | --- | |
58 | kernel/bpf/verifier.c | 2 +- | |
59 | 1 file changed, 1 insertion(+), 1 deletion(-) | |
60 | ||
61 | --- a/kernel/bpf/verifier.c | |
62 | +++ b/kernel/bpf/verifier.c | |
63 | @@ -3187,7 +3187,7 @@ do_sim: | |
64 | *dst_reg = *ptr_reg; | |
65 | } | |
66 | ret = push_stack(env, env->insn_idx + 1, env->insn_idx, true); | |
67 | - if (!ptr_is_dst_reg) | |
68 | + if (!ptr_is_dst_reg && ret) | |
69 | *dst_reg = tmp; | |
70 | return !ret ? -EFAULT : 0; | |
71 | } |