In the Linux kernel, the following vulnerability has been resolved:
bpf: Reject variable offset alu on PTRTOFLOW_KEYS
For PTRTOFLOWKEYS, checkflowkeysaccess() 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() R6w=ctx() 1: (79) r7 = *(u64 *)(r6 +144) ; R6w=ctx() R7w=flowkeys() 2: (b7) r8 = 1024 ; R8w=1024 3: (37) r8 /= 1 ; R8w=scalar() 4: (57) r8 &= 1024 ; R8w=scalar(smin=smin32=0, smax=umax=smax32=umax32=1024,varoff=(0x0; 0x400)) 5: (0f) r7 += r8 markprecise: frame0: lastidx 5 firstidx 0 subseqidx -1 markprecise: frame0: regs=r8 stack= before 4: (57) r8 &= 1024 markprecise: frame0: regs=r8 stack= before 3: (37) r8 /= 1 markprecise: frame0: regs=r8 stack= before 2: (b7) r8 = 1024 6: R7w=flowkeys(smin=smin32=0,smax=umax=smax32=umax32=1024,varoff =(0x0; 0x400)) R8w=scalar(smin=smin32=0,smax=umax=smax32=umax32=1024, varoff=(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> bpfdispatchernopfunc include/linux/bpf.h:1231 [inline] _bpfprogrun include/linux/filter.h:651 [inline] bpfprogrun include/linux/filter.h:658 [inline] bpfprogrunpinoncpu include/linux/filter.h:675 [inline] bpfflowdissect+0x15f/0x350 net/core/flowdissector.c:991 bpfprogtestrunflowdissector+0x39d/0x620 net/bpf/testrun.c:1359 bpfprogtestrun kernel/bpf/syscall.c:4107 [inline] _sysbpf+0xf8f/0x4560 kernel/bpf/syscall.c:5475 _dosysbpf kernel/bpf/syscall.c:5561 [inline] _sesysbpf kernel/bpf/syscall.c:5559 [inline] _x64sysbpf+0x73/0xb0 kernel/bpf/syscall.c:5559 dosyscallx64 arch/x86/entry/common.c:52 [inline] dosyscall64+0x3f/0x110 arch/x86/entry/common.c:83 entrySYSCALL64afterhwframe+0x63/0x6b
Fix this by rejecting ptr alu with variable offset on flowkeys. Applying the patch rejects the program with "R7 pointer arithmetic on flowkeys prohibited".