In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
Inthe Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]Since the verifier is analyzing the false branch of the conditional jump,reg1 is equal to false_reg1 and reg2 is equal to false_reg2, i.e. the reg2is the "fake" register that was meant to hold a constant value. The resultingvar_off of the intersection says that both registers now hold a known valueof var_off=(0x7fffffff, 0x0) or in other words: this operation manages tomake the verifier think that the "constant" value that was passed in thejump operation now holds a different value.Normally this would not be an issue since it should not influence the truebranch, however, false_reg2 and true_reg2 are pointers to the same "fake"register. Meaning, the false branch can influence the results of the truebranch. In line 24, the verifier assumes R6_w=0, but the actual runtimevalue in this case is 1. The fix is simply not passing in the same "fake"register location as inputs to reg_set_min_max(), but instead making acopy. Moving the fake_reg into the env also reduces stack consumption by120 bytes. With this, the verifier successfully rejects invalid accessesfrom the test program. [0] <ahref= https://github.com/google/buzzer >https://github.com/google/buzzer</a>The Linux kernel CVE team has assigned CVE-2024-41003 to this issue.
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]Since the verifier is analyzing the false branch of the conditional jump,reg1 is equal to false_reg1 and reg2 is equal to false_reg2, i.e. the reg2is the "fake" register that was meant to hold a constant value. The resultingvar_off of the intersection says that both registers now hold a known valueof var_off=(0x7fffffff, 0x0) or in other words: this operation manages tomake the verifier think that the "constant" value that was passed in thejump operation now holds a different value.Normally this would not be an issue since it should not influence the truebranch, however, false_reg2 and true_reg2 are pointers to the same "fake"register. Meaning, the false branch can influence the results of the truebranch. In line 24, the verifier assumes R6_w=0, but the actual runtimevalue in this case is 1. The fix is simply not passing in the same "fake"register location as inputs to reg_set_min_max(), but instead making acopy. Moving the fake_reg into the env also reduces stack consumption by120 bytes. With this, the verifier successfully rejects invalid accessesfrom the test program. [0] <ahref= https://github.com/google/buzzer >https://github.com/google/buzzer</a>The Linux kernel CVE team has assigned CVE-2024-41003 to this issue.
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]Since the verifier is an
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]Since the verifier is an
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...]Since the verifier is
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]Since the verifier is
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...]Since the verifier
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]Since the verifier
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]Since the verifier
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]Since the verifier
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]Since the verifier
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]Since the verifier
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...]Since the verifie
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]Since the verifie
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...]Since the verif
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]Since the verif
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...]Since the ver
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]Since the ver
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]Since the ver
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]Since the ver
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...]Since the v
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]Since the v
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...]Since the
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]Since the
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...]Since t
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]Since t
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...]Since
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]Since
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...]Sin
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]Sin
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]Sin
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]Sin
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...]S
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]S
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]S
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]S
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...]S
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...]S
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [...
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [...
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [...
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t); [.
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [.
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t); [.
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t); [.
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t);
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t);
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t);
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 =*(u64 *)(r0 +0) ;R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 =0;R0_w=0 15: (b4) w0 =-1 ;R0_w=0xffffffff 16: (74) w0 >>= 1;R0_w=0x7fffffff 17: (5c) w6 &= w0 ;R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2;R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ;R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ;R6_w=0 [...]What can be seen here is aregister invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2is set but knowsnothing about the rest of the content which was loaded from amap value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is aknown constant.Internally, the verifier creates a"fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(11111101).When the verifier first analyzes the false /fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a"fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t=tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off =tnum_with_subreg(reg1->var_off, t); reg2->var_off =tnum_with_subreg(reg2->var_off, t);
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6= *(u64 *)(r0 +0); R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0=0; R0_w=0 15: (b4) w0= -1; R0_w=0xffffffff 16: (74) w0 >>=1; R0_w=0x7fffffff 17: (5c) w6 &= w0; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |=2; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14; R6_w=0 [...]What can be seen here isa register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit2 is set but knowsnothing about the rest of the content which was loaded froma map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg isa known constant.Internally, the verifier createsa "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false/ fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier createsa "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t= tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off= tnum_with_subreg(reg1->var_off, t); reg2->var_off= tnum_with_subreg(reg2->var_off, t
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
| linux | | https://git.kernel.org/linus/92424801261d1564a0bb759da3cf3ccd69fdf5a2 | https://git.kernel.org/linus/67420501e8681ae18f9f0ea0a69cd2f432100e70 | ubuntu |
</details>
二、漏洞分析结构反馈
影响性分析说明:
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a "fake" register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a "fake" register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_off = tnum_with_subreg(reg1->var_off, t); reg2->var_off = tnum_with_subreg(reg2->var_off, t
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Fix reg_set_min_max corruption of fake_regJuan reported that after doing some changes to buzzer [0] and implementinga new fuzzing strategy guided by coverage, they noticed the following inone of the probes: [...] 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar() 14: (b7) r0 = 0 ; R0_w=0 15: (b4) w0 = -1 ; R0_w=0xffffffff 16: (74) w0 >>= 1 ; R0_w=0x7fffffff 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff)) 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd)) 19: (56) if w6 != 0x7ffffffd goto pc+1 REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0) REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0) 19: R6_w=0x7fffffff 20: (95) exit from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd)) 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd)) 23: (95) exit from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm 24: (14) w6 -= 14 ; R6_w=0 [...]What can be seen here is a register invariant violation on line 19. Afterthe binary-or in line 18, the verifier knows that bit 2 is set but knowsnothing about the rest of the content which was loaded from a map value,meaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When inline 19 the verifier analyzes the branch, it splits the register statesin reg_set_min_max() into the registers of the true branch (true_reg1,true_reg2) and the registers of the false branch (false_reg1, false_reg2).Since the test is w6 != 0x7ffffffd, the src_reg is a known constant.Internally, the verifier creates a fake register initialized as scalarto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,for line 19, it is mathematically impossible to take the false branch ofthis program, yet the verifier analyzes it. It is impossible because thesecond bit of r6 will be set due to the prior or operation and theconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).When the verifier first analyzes the false / fall-through branch, it willcompute an intersection between the var_off of r6 and of the constant. Thisis because the verifier creates a fake register initialized to the valueof the constant. The intersection result later refines both registers inregs_refine_cond_op(): [...] t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off)); reg1->var_o---truncated---