public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf] bpf: verifier: fix NULL pointer dereference in do_misc_fixups()
@ 2024-03-22 14:38 Puranjay Mohan
  2024-03-22 15:37 ` Puranjay Mohan
  0 siblings, 1 reply; 2+ messages in thread
From: Puranjay Mohan @ 2024-03-22 14:38 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
	Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, bpf, linux-kernel,
	linux-riscv
  Cc: puranjay12

The addr_space_cast instruction is convered to a normal 32 bit mov by the
verifier if the cast from as(0) to as(1) or if the user has set the flag
BPF_F_NO_USER_CONV in the arena.

If the BPF program doesn't have an associated arena
env->prog->aux->arena is NULL and the verifier currently doesn't check
for it being NULL before accessing map_flags. This can cause a NULL
pointer dereference:

root@rv-tester:~# ./reproducer
 Unable to handle kernel access to user memory without uaccess routines at virtual address 0000000000000030
 Oops [#1]
 Modules linked in: sch_fq_codel drm fuse i2c_core drm_panel_orientation_quirks backlight configfs ip_tables x_tables
 CPU: 2 PID: 265 Comm: reproducer Not tainted 6.8.0 #3
 Hardware name: riscv-virtio,qemu (DT)
 epc : do_misc_fixups+0x43c/0x1168
  ra : bpf_check+0xda8/0x22b6
 epc : ffffffff8017eeaa ra : ffffffff801936d6 sp : ff200000011bb890
  gp : ffffffff82293468 tp : ff60000084fcb840 t0 : ff60000084e38048
  t1 : 0000000000000048 t2 : ff5fffff80000000 s0 : ff200000011bba60
  s1 : ff2000000101d058 a0 : ff6000008b980000 a1 : 0000000000000004
  a2 : 00000000000000e1 a3 : 0000000000000001 a4 : 0000000000010000
  a5 : 0000000000000000 a6 : 0000000000000001 a7 : ff2000000101d000
  s2 : 0000000000000002 s3 : 0000000000000000 s4 : 0000000000000000
  s5 : 0000000000000002 s6 : 0000000000000000 s7 : ff6000008b980aa0
  s8 : 0000000000010005 s9 : 0000000000000004 s10: ff6000008b980000
  s11: 0000000000000000 t3 : 0000000000002000 t4 : 0000ff0000000000
  t5 : 00ff000000000000 t6 : ff20000000000000
 status: 0000000200000120 badaddr: 0000000000000030 cause: 000000000000000d
 [<ffffffff8017eeaa>] do_misc_fixups+0x43c/0x1168
 [<ffffffff801936d6>] bpf_check+0xda8/0x22b6
 [<ffffffff80174b32>] bpf_prog_load+0x486/0x8dc
 [<ffffffff80176566>] __sys_bpf+0xbd8/0x214e
 [<ffffffff80177d14>] __riscv_sys_bpf+0x22/0x2a
 [<ffffffff80d2493a>] do_trap_ecall_u+0x102/0x17c
 [<ffffffff80d3048c>] ret_from_exception+0x0/0x64
 Code: b345 9783 0024 4685 8b63 16d7 3783 008d 7f9c 7fdc (5b9c) 83c9
 ---[ end trace 0000000000000000 ]---
 Kernel panic - not syncing: Fatal exception
 SMP: stopping secondary CPUs

Add a check for NULL pointer before checking map_flags.

Fixes: 6082b6c328b5 ("bpf: Recognize addr_space_cast instruction in the verifier.")
Reported-by: xingwei lee <xrivendell7@gmail.com>
Reported-by: yue sun <samsun1006219@gmail.com>
Closes: https://lore.kernel.org/bpf/CABOYnLz09O1+2gGVJuCxd_24a-7UueXzV-Ff+Fr+h5EKFDiYCQ@mail.gmail.com/
Signed-off-by: Puranjay Mohan <puranjay12@gmail.com>
---
 kernel/bpf/verifier.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index ca6cacf7b42f..78945e7b856d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -19607,7 +19607,8 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
 	for (i = 0; i < insn_cnt;) {
 		if (insn->code == (BPF_ALU64 | BPF_MOV | BPF_X) && insn->imm) {
 			if ((insn->off == BPF_ADDR_SPACE_CAST && insn->imm == 1) ||
-			    (((struct bpf_map *)env->prog->aux->arena)->map_flags & BPF_F_NO_USER_CONV)) {
+			    (env->prog->aux->arena &&
+			     (((struct bpf_map *)env->prog->aux->arena)->map_flags & BPF_F_NO_USER_CONV))) {
 				/* convert to 32-bit mov that clears upper 32-bit */
 				insn->code = BPF_ALU | BPF_MOV | BPF_X;
 				/* clear off, so it's a normal 'wX = wY' from JIT pov */
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH bpf] bpf: verifier: fix NULL pointer dereference in do_misc_fixups()
  2024-03-22 14:38 [PATCH bpf] bpf: verifier: fix NULL pointer dereference in do_misc_fixups() Puranjay Mohan
@ 2024-03-22 15:37 ` Puranjay Mohan
  0 siblings, 0 replies; 2+ messages in thread
From: Puranjay Mohan @ 2024-03-22 15:37 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
	Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, bpf, linux-kernel,
	linux-riscv, Kumar Kartikeya Dwivedi

Puranjay Mohan <puranjay12@gmail.com> writes:

> The addr_space_cast instruction is convered to a normal 32 bit mov by the
> verifier if the cast from as(0) to as(1) or if the user has set the flag
> BPF_F_NO_USER_CONV in the arena.
>
> If the BPF program doesn't have an associated arena
> env->prog->aux->arena is NULL and the verifier currently doesn't check
> for it being NULL before accessing map_flags. This can cause a NULL
> pointer dereference:
>
> root@rv-tester:~# ./reproducer
>  Unable to handle kernel access to user memory without uaccess routines at virtual address 0000000000000030
>  Oops [#1]
>  Modules linked in: sch_fq_codel drm fuse i2c_core drm_panel_orientation_quirks backlight configfs ip_tables x_tables
>  CPU: 2 PID: 265 Comm: reproducer Not tainted 6.8.0 #3
>  Hardware name: riscv-virtio,qemu (DT)
>  epc : do_misc_fixups+0x43c/0x1168
>   ra : bpf_check+0xda8/0x22b6
>  epc : ffffffff8017eeaa ra : ffffffff801936d6 sp : ff200000011bb890
>   gp : ffffffff82293468 tp : ff60000084fcb840 t0 : ff60000084e38048
>   t1 : 0000000000000048 t2 : ff5fffff80000000 s0 : ff200000011bba60
>   s1 : ff2000000101d058 a0 : ff6000008b980000 a1 : 0000000000000004
>   a2 : 00000000000000e1 a3 : 0000000000000001 a4 : 0000000000010000
>   a5 : 0000000000000000 a6 : 0000000000000001 a7 : ff2000000101d000
>   s2 : 0000000000000002 s3 : 0000000000000000 s4 : 0000000000000000
>   s5 : 0000000000000002 s6 : 0000000000000000 s7 : ff6000008b980aa0
>   s8 : 0000000000010005 s9 : 0000000000000004 s10: ff6000008b980000
>   s11: 0000000000000000 t3 : 0000000000002000 t4 : 0000ff0000000000
>   t5 : 00ff000000000000 t6 : ff20000000000000
>  status: 0000000200000120 badaddr: 0000000000000030 cause: 000000000000000d
>  [<ffffffff8017eeaa>] do_misc_fixups+0x43c/0x1168
>  [<ffffffff801936d6>] bpf_check+0xda8/0x22b6
>  [<ffffffff80174b32>] bpf_prog_load+0x486/0x8dc
>  [<ffffffff80176566>] __sys_bpf+0xbd8/0x214e
>  [<ffffffff80177d14>] __riscv_sys_bpf+0x22/0x2a
>  [<ffffffff80d2493a>] do_trap_ecall_u+0x102/0x17c
>  [<ffffffff80d3048c>] ret_from_exception+0x0/0x64
>  Code: b345 9783 0024 4685 8b63 16d7 3783 008d 7f9c 7fdc (5b9c) 83c9
>  ---[ end trace 0000000000000000 ]---
>  Kernel panic - not syncing: Fatal exception
>  SMP: stopping secondary CPUs
>
> Add a check for NULL pointer before checking map_flags.
>
> Fixes: 6082b6c328b5 ("bpf: Recognize addr_space_cast instruction in the verifier.")
> Reported-by: xingwei lee <xrivendell7@gmail.com>
> Reported-by: yue sun <samsun1006219@gmail.com>
> Closes: https://lore.kernel.org/bpf/CABOYnLz09O1+2gGVJuCxd_24a-7UueXzV-Ff+Fr+h5EKFDiYCQ@mail.gmail.com/
> Signed-off-by: Puranjay Mohan <puranjay12@gmail.com>
> ---
>  kernel/bpf/verifier.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index ca6cacf7b42f..78945e7b856d 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -19607,7 +19607,8 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
>  	for (i = 0; i < insn_cnt;) {
>  		if (insn->code == (BPF_ALU64 | BPF_MOV | BPF_X) && insn->imm) {
>  			if ((insn->off == BPF_ADDR_SPACE_CAST && insn->imm == 1) ||
> -			    (((struct bpf_map *)env->prog->aux->arena)->map_flags & BPF_F_NO_USER_CONV)) {
> +			    (env->prog->aux->arena &&

Kumar made me aware of the fact that env->prog->aux_arena should never
be NULL if the program has an addr_space_cast instruction. This means
that rather than checking for the NULL pointer here and leaving the
addr_space_cast as it is, We should reject programs that contain an
addr_space_cast instruction but don't have an associated arena.

Sent v2 doing the above: https://lore.kernel.org/bpf/20240322153518.11555-1-puranjay12@gmail.com/


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-03-22 15:37 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-22 14:38 [PATCH bpf] bpf: verifier: fix NULL pointer dereference in do_misc_fixups() Puranjay Mohan
2024-03-22 15:37 ` Puranjay Mohan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox