Message ID | 20240314194617.42266-1-bethany.jamison@canonical.com |
---|---|
Headers | show |
Series | CVE-2024-26589 | expand |
On 14.03.24 20:46, Bethany Jamison wrote: > [Impact] > > In the Linux kernel, the following vulnerability has been resolved: > > bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS > > For PTR_TO_FLOW_KEYS, check_flow_keys_access() only uses fixed off > for validation. However, variable offset ptr alu is not prohibited > for this ptr kind. So the variable offset is not checked. > > The following prog is accepted: > > func#0 @0 > 0: R1=ctx() R10=fp0 > 0: (bf) r6 = r1 ; R1=ctx() R6_w=ctx() > 1: (79) r7 = *(u64 *)(r6 +144) ; R6_w=ctx() R7_w=flow_keys() > 2: (b7) r8 = 1024 ; R8_w=1024 > 3: (37) r8 /= 1 ; R8_w=scalar() > 4: (57) r8 &= 1024 ; R8_w=scalar(smin=smin32=0, > smax=umax=smax32=umax32=1024,var_off=(0x0; 0x400)) > 5: (0f) r7 += r8 > mark_precise: frame0: last_idx 5 first_idx 0 subseq_idx -1 > mark_precise: frame0: regs=r8 stack= before 4: (57) r8 &= 1024 > mark_precise: frame0: regs=r8 stack= before 3: (37) r8 /= 1 > mark_precise: frame0: regs=r8 stack= before 2: (b7) r8 = 1024 > 6: R7_w=flow_keys(smin=smin32=0,smax=umax=smax32=umax32=1024,var_off > =(0x0; 0x400)) R8_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=1024, > var_off=(0x0; 0x400)) > 6: (79) r0 = *(u64 *)(r7 +0) ; R0_w=scalar() > 7: (95) exit > > This prog loads flow_keys to r7, and adds the variable offset r8 > to r7, and finally causes out-of-bounds access: > > BUG: unable to handle page fault for address: ffffc90014c80038 > [...] > Call Trace: > <TASK> > bpf_dispatcher_nop_func include/linux/bpf.h:1231 [inline] > __bpf_prog_run include/linux/filter.h:651 [inline] > bpf_prog_run include/linux/filter.h:658 [inline] > bpf_prog_run_pin_on_cpu include/linux/filter.h:675 [inline] > bpf_flow_dissect+0x15f/0x350 net/core/flow_dissector.c:991 > bpf_prog_test_run_flow_dissector+0x39d/0x620 net/bpf/test_run.c:1359 > bpf_prog_test_run kernel/bpf/syscall.c:4107 [inline] > __sys_bpf+0xf8f/0x4560 kernel/bpf/syscall.c:5475 > __do_sys_bpf kernel/bpf/syscall.c:5561 [inline] > __se_sys_bpf kernel/bpf/syscall.c:5559 [inline] > __x64_sys_bpf+0x73/0xb0 kernel/bpf/syscall.c:5559 > do_syscall_x64 arch/x86/entry/common.c:52 [inline] > do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:83 > entry_SYSCALL_64_after_hwframe+0x63/0x6b > > Fix this by rejecting ptr alu with variable offset on flow_keys. > Applying the patch rejects the program with "R7 pointer arithmetic > on flow_keys prohibited". > > [Fix] > > Mantic: Clean cherry-pick. > Focal: Backport - Upstream moved a case statement out of the > 'switch (ptr_reg->type)' switch block to an if block right before the > switch. Functionally, it doesn't matter if that code exists before or > at the beginning of the switch block as the logic isn't affected. Focal > keeps the case statement inside the switch statement and cherry-picking > my way to merge upstream and Focal wasn't feasible. I kept Focal as is and > added the change from the fix commit (an additional case statement inside > the 'switch (ptr_reg->type' switch block). This does not mention Jammy which could be simply because it got already there via stable. But it helps a lot to mention it when submitting. Because affecting every kernel in a range is more normal. > > [Test Case] > > Compile and boot tested. > > [Where problems could occur] > > This will affect those who use bpf, this has some risk of > regression because of the manual backporting that was requried. > > Hao Sun (1): > bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS > > kernel/bpf/verifier.c | 4 ++++ > 1 file changed, 4 insertions(+) > Acked-by: Stefan Bader <stefan.bader@canonical.com>
On 3/14/24 22:46, Bethany Jamison wrote: > [Impact] > > In the Linux kernel, the following vulnerability has been resolved: > > bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS > > For PTR_TO_FLOW_KEYS, check_flow_keys_access() only uses fixed off > for validation. However, variable offset ptr alu is not prohibited > for this ptr kind. So the variable offset is not checked. > > The following prog is accepted: > > func#0 @0 > 0: R1=ctx() R10=fp0 > 0: (bf) r6 = r1 ; R1=ctx() R6_w=ctx() > 1: (79) r7 = *(u64 *)(r6 +144) ; R6_w=ctx() R7_w=flow_keys() > 2: (b7) r8 = 1024 ; R8_w=1024 > 3: (37) r8 /= 1 ; R8_w=scalar() > 4: (57) r8 &= 1024 ; R8_w=scalar(smin=smin32=0, > smax=umax=smax32=umax32=1024,var_off=(0x0; 0x400)) > 5: (0f) r7 += r8 > mark_precise: frame0: last_idx 5 first_idx 0 subseq_idx -1 > mark_precise: frame0: regs=r8 stack= before 4: (57) r8 &= 1024 > mark_precise: frame0: regs=r8 stack= before 3: (37) r8 /= 1 > mark_precise: frame0: regs=r8 stack= before 2: (b7) r8 = 1024 > 6: R7_w=flow_keys(smin=smin32=0,smax=umax=smax32=umax32=1024,var_off > =(0x0; 0x400)) R8_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=1024, > var_off=(0x0; 0x400)) > 6: (79) r0 = *(u64 *)(r7 +0) ; R0_w=scalar() > 7: (95) exit > > This prog loads flow_keys to r7, and adds the variable offset r8 > to r7, and finally causes out-of-bounds access: > > BUG: unable to handle page fault for address: ffffc90014c80038 > [...] > Call Trace: > <TASK> > bpf_dispatcher_nop_func include/linux/bpf.h:1231 [inline] > __bpf_prog_run include/linux/filter.h:651 [inline] > bpf_prog_run include/linux/filter.h:658 [inline] > bpf_prog_run_pin_on_cpu include/linux/filter.h:675 [inline] > bpf_flow_dissect+0x15f/0x350 net/core/flow_dissector.c:991 > bpf_prog_test_run_flow_dissector+0x39d/0x620 net/bpf/test_run.c:1359 > bpf_prog_test_run kernel/bpf/syscall.c:4107 [inline] > __sys_bpf+0xf8f/0x4560 kernel/bpf/syscall.c:5475 > __do_sys_bpf kernel/bpf/syscall.c:5561 [inline] > __se_sys_bpf kernel/bpf/syscall.c:5559 [inline] > __x64_sys_bpf+0x73/0xb0 kernel/bpf/syscall.c:5559 > do_syscall_x64 arch/x86/entry/common.c:52 [inline] > do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:83 > entry_SYSCALL_64_after_hwframe+0x63/0x6b > > Fix this by rejecting ptr alu with variable offset on flow_keys. > Applying the patch rejects the program with "R7 pointer arithmetic > on flow_keys prohibited". > > [Fix] > > Mantic: Clean cherry-pick. > Focal: Backport - Upstream moved a case statement out of the > 'switch (ptr_reg->type)' switch block to an if block right before the > switch. Functionally, it doesn't matter if that code exists before or > at the beginning of the switch block as the logic isn't affected. Focal > keeps the case statement inside the switch statement and cherry-picking > my way to merge upstream and Focal wasn't feasible. I kept Focal as is and > added the change from the fix commit (an additional case statement inside > the 'switch (ptr_reg->type' switch block). > > [Test Case] > > Compile and boot tested. > > [Where problems could occur] > > This will affect those who use bpf, this has some risk of > regression because of the manual backporting that was requried. > > Hao Sun (1): > bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS Acked-by: Cengiz Can <cengiz.can@canonical.com> > > kernel/bpf/verifier.c | 4 ++++ > 1 file changed, 4 insertions(+) >
On 14.03.24 20:46, Bethany Jamison wrote: > [Impact] > > In the Linux kernel, the following vulnerability has been resolved: > > bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS > > For PTR_TO_FLOW_KEYS, check_flow_keys_access() only uses fixed off > for validation. However, variable offset ptr alu is not prohibited > for this ptr kind. So the variable offset is not checked. > > The following prog is accepted: > > func#0 @0 > 0: R1=ctx() R10=fp0 > 0: (bf) r6 = r1 ; R1=ctx() R6_w=ctx() > 1: (79) r7 = *(u64 *)(r6 +144) ; R6_w=ctx() R7_w=flow_keys() > 2: (b7) r8 = 1024 ; R8_w=1024 > 3: (37) r8 /= 1 ; R8_w=scalar() > 4: (57) r8 &= 1024 ; R8_w=scalar(smin=smin32=0, > smax=umax=smax32=umax32=1024,var_off=(0x0; 0x400)) > 5: (0f) r7 += r8 > mark_precise: frame0: last_idx 5 first_idx 0 subseq_idx -1 > mark_precise: frame0: regs=r8 stack= before 4: (57) r8 &= 1024 > mark_precise: frame0: regs=r8 stack= before 3: (37) r8 /= 1 > mark_precise: frame0: regs=r8 stack= before 2: (b7) r8 = 1024 > 6: R7_w=flow_keys(smin=smin32=0,smax=umax=smax32=umax32=1024,var_off > =(0x0; 0x400)) R8_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=1024, > var_off=(0x0; 0x400)) > 6: (79) r0 = *(u64 *)(r7 +0) ; R0_w=scalar() > 7: (95) exit > > This prog loads flow_keys to r7, and adds the variable offset r8 > to r7, and finally causes out-of-bounds access: > > BUG: unable to handle page fault for address: ffffc90014c80038 > [...] > Call Trace: > <TASK> > bpf_dispatcher_nop_func include/linux/bpf.h:1231 [inline] > __bpf_prog_run include/linux/filter.h:651 [inline] > bpf_prog_run include/linux/filter.h:658 [inline] > bpf_prog_run_pin_on_cpu include/linux/filter.h:675 [inline] > bpf_flow_dissect+0x15f/0x350 net/core/flow_dissector.c:991 > bpf_prog_test_run_flow_dissector+0x39d/0x620 net/bpf/test_run.c:1359 > bpf_prog_test_run kernel/bpf/syscall.c:4107 [inline] > __sys_bpf+0xf8f/0x4560 kernel/bpf/syscall.c:5475 > __do_sys_bpf kernel/bpf/syscall.c:5561 [inline] > __se_sys_bpf kernel/bpf/syscall.c:5559 [inline] > __x64_sys_bpf+0x73/0xb0 kernel/bpf/syscall.c:5559 > do_syscall_x64 arch/x86/entry/common.c:52 [inline] > do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:83 > entry_SYSCALL_64_after_hwframe+0x63/0x6b > > Fix this by rejecting ptr alu with variable offset on flow_keys. > Applying the patch rejects the program with "R7 pointer arithmetic > on flow_keys prohibited". > > [Fix] > > Mantic: Clean cherry-pick. > Focal: Backport - Upstream moved a case statement out of the > 'switch (ptr_reg->type)' switch block to an if block right before the > switch. Functionally, it doesn't matter if that code exists before or > at the beginning of the switch block as the logic isn't affected. Focal > keeps the case statement inside the switch statement and cherry-picking > my way to merge upstream and Focal wasn't feasible. I kept Focal as is and > added the change from the fix commit (an additional case statement inside > the 'switch (ptr_reg->type' switch block). > > [Test Case] > > Compile and boot tested. > > [Where problems could occur] > > This will affect those who use bpf, this has some risk of > regression because of the manual backporting that was requried. > > Hao Sun (1): > bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS > > kernel/bpf/verifier.c | 4 ++++ > 1 file changed, 4 insertions(+) > Applied to focal:linux/master-next. For Mantic this was already applied as part of "upstream stable patchset 2024-03-07". I just added the CVE number to the commit. Thanks. -Stefan