{"dataType":"CVE_RECORD","dataVersion":"5.1","cveMetadata":{"cveId":"CVE-2022-49658","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","state":"PUBLISHED","assignerShortName":"Linux","dateReserved":"2025-02-26T02:21:30.434Z","datePublished":"2025-02-26T02:23:56.922Z","dateUpdated":"2025-05-04T08:42:44.420Z"},"containers":{"cna":{"providerMetadata":{"orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","shortName":"Linux","dateUpdated":"2025-05-04T08:42:44.420Z"},"descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nbpf: Fix insufficient bounds propagation from adjust_scalar_min_max_vals\n\nKuee reported a corner case where the tnum becomes constant after the call\nto __reg_bound_offset(), but the register's bounds are not, that is, its\nmin bounds are still not equal to the register's max bounds.\n\nThis in turn allows to leak pointers through turning a pointer register as\nis into an unknown scalar via adjust_ptr_min_max_vals().\n\nBefore:\n\n  func#0 @0\n  0: R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0))\n  0: (b7) r0 = 1                        ; R0_w=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0))\n  1: (b7) r3 = 0                        ; R3_w=scalar(imm=0,umax=0,var_off=(0x0; 0x0))\n  2: (87) r3 = -r3                      ; R3_w=scalar()\n  3: (87) r3 = -r3                      ; R3_w=scalar()\n  4: (47) r3 |= 32767                   ; R3_w=scalar(smin=-9223372036854743041,umin=32767,var_off=(0x7fff; 0xffffffffffff8000),s32_min=-2147450881)\n  5: (75) if r3 s>= 0x0 goto pc+1       ; R3_w=scalar(umin=9223372036854808575,var_off=(0x8000000000007fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767)\n  6: (95) exit\n\n  from 5 to 7: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0))\n  7: (d5) if r3 s<= 0x8000 goto pc+1    ; R3=scalar(umin=32769,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767)\n  8: (95) exit\n\n  from 7 to 9: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=32768,var_off=(0x7fff; 0x8000)) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0))\n  9: (07) r3 += -32767                  ; R3_w=scalar(imm=0,umax=1,var_off=(0x0; 0x0))  <--- [*]\n  10: (95) exit\n\nWhat can be seen here is that R3=scalar(umin=32767,umax=32768,var_off=(0x7fff;\n0x8000)) after the operation R3 += -32767 results in a 'malformed' constant, that\nis, R3_w=scalar(imm=0,umax=1,var_off=(0x0; 0x0)). Intersecting with var_off has\nnot been done at that point via __update_reg_bounds(), which would have improved\nthe umax to be equal to umin.\n\nRefactor the tnum <> min/max bounds information flow into a reg_bounds_sync()\nhelper and use it consistently everywhere. After the fix, bounds have been\ncorrected to R3_w=scalar(imm=0,umax=0,var_off=(0x0; 0x0)) and thus the register\nis regarded as a 'proper' constant scalar of 0.\n\nAfter:\n\n  func#0 @0\n  0: R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0))\n  0: (b7) r0 = 1                        ; R0_w=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0))\n  1: (b7) r3 = 0                        ; R3_w=scalar(imm=0,umax=0,var_off=(0x0; 0x0))\n  2: (87) r3 = -r3                      ; R3_w=scalar()\n  3: (87) r3 = -r3                      ; R3_w=scalar()\n  4: (47) r3 |= 32767                   ; R3_w=scalar(smin=-9223372036854743041,umin=32767,var_off=(0x7fff; 0xffffffffffff8000),s32_min=-2147450881)\n  5: (75) if r3 s>= 0x0 goto pc+1       ; R3_w=scalar(umin=9223372036854808575,var_off=(0x8000000000007fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767)\n  6: (95) exit\n\n  from 5 to 7: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0))\n  7: (d5) if r3 s<= 0x8000 goto pc+1    ; R3=scalar(umin=32769,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767)\n  8: (95) exit\n\n  from 7 to 9: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=32768,var_off=(0x7fff; 0x8000)) R10=fp(off=0\n---truncated---"}],"affected":[{"product":"Linux","vendor":"Linux","defaultStatus":"unaffected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["kernel/bpf/verifier.c"],"versions":[{"version":"b03c9f9fdc37dab81ea04d5dacdc5995d4c224c2","lessThan":"e917be1f83ea14a68b3cf64d3da9968eaf991dae","status":"affected","versionType":"git"},{"version":"b03c9f9fdc37dab81ea04d5dacdc5995d4c224c2","lessThan":"a7de8d436db92bab8b1f44624297c2554a6ac36b","status":"affected","versionType":"git"},{"version":"b03c9f9fdc37dab81ea04d5dacdc5995d4c224c2","lessThan":"b2a28bb36664c94375926cbbb91976242847699d","status":"affected","versionType":"git"},{"version":"b03c9f9fdc37dab81ea04d5dacdc5995d4c224c2","lessThan":"3844d153a41adea718202c10ae91dc96b37453b5","status":"affected","versionType":"git"}]},{"product":"Linux","vendor":"Linux","defaultStatus":"affected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["kernel/bpf/verifier.c"],"versions":[{"version":"4.14","status":"affected"},{"version":"0","lessThan":"4.14","status":"unaffected","versionType":"semver"},{"version":"5.10.130","lessThanOrEqual":"5.10.*","status":"unaffected","versionType":"semver"},{"version":"5.15.54","lessThanOrEqual":"5.15.*","status":"unaffected","versionType":"semver"},{"version":"5.18.11","lessThanOrEqual":"5.18.*","status":"unaffected","versionType":"semver"},{"version":"5.19","lessThanOrEqual":"*","status":"unaffected","versionType":"original_commit_for_fix"}]}],"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"4.14","versionEndExcluding":"5.10.130"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"4.14","versionEndExcluding":"5.15.54"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"4.14","versionEndExcluding":"5.18.11"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"4.14","versionEndExcluding":"5.19"}]}]}],"references":[{"url":"https://git.kernel.org/stable/c/e917be1f83ea14a68b3cf64d3da9968eaf991dae"},{"url":"https://git.kernel.org/stable/c/a7de8d436db92bab8b1f44624297c2554a6ac36b"},{"url":"https://git.kernel.org/stable/c/b2a28bb36664c94375926cbbb91976242847699d"},{"url":"https://git.kernel.org/stable/c/3844d153a41adea718202c10ae91dc96b37453b5"}],"title":"bpf: Fix insufficient bounds propagation from adjust_scalar_min_max_vals","x_generator":{"engine":"bippy-1.2.0"}}}}