This is a note to let you know that I've just added the patch titled bpf: Make 32->64 bounds propagation slightly more robust to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: bpf-make-32-64-bounds-propagation-slightly-more-robust.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From e572ff80f05c33cd0cb4860f864f5c9c044280b6 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann <daniel@xxxxxxxxxxxxx> Date: Wed, 15 Dec 2021 22:28:48 +0000 Subject: bpf: Make 32->64 bounds propagation slightly more robust From: Daniel Borkmann <daniel@xxxxxxxxxxxxx> commit e572ff80f05c33cd0cb4860f864f5c9c044280b6 upstream. Make the bounds propagation in __reg_assign_32_into_64() slightly more robust and readable by aligning it similarly as we did back in the __reg_combine_64_into_32() counterpart. Meaning, only propagate or pessimize them as a smin/smax pair. Signed-off-by: Daniel Borkmann <daniel@xxxxxxxxxxxxx> Reviewed-by: John Fastabend <john.fastabend@xxxxxxxxx> Acked-by: Alexei Starovoitov <ast@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- kernel/bpf/verifier.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1358,22 +1358,28 @@ static void __reg_bound_offset(struct bp reg->var_off = tnum_or(tnum_clear_subreg(var64_off), var32_off); } +static bool __reg32_bound_s64(s32 a) +{ + return a >= 0 && a <= S32_MAX; +} + static void __reg_assign_32_into_64(struct bpf_reg_state *reg) { reg->umin_value = reg->u32_min_value; reg->umax_value = reg->u32_max_value; - /* Attempt to pull 32-bit signed bounds into 64-bit bounds - * but must be positive otherwise set to worse case bounds - * and refine later from tnum. + + /* Attempt to pull 32-bit signed bounds into 64-bit bounds but must + * be positive otherwise set to worse case bounds and refine later + * from tnum. */ - if (reg->s32_min_value >= 0 && reg->s32_max_value >= 0) - reg->smax_value = reg->s32_max_value; - else - reg->smax_value = U32_MAX; - if (reg->s32_min_value >= 0) + if (__reg32_bound_s64(reg->s32_min_value) && + __reg32_bound_s64(reg->s32_max_value)) { reg->smin_value = reg->s32_min_value; - else + reg->smax_value = reg->s32_max_value; + } else { reg->smin_value = 0; + reg->smax_value = U32_MAX; + } } static void __reg_combine_32_into_64(struct bpf_reg_state *reg) Patches currently in stable-queue which might be from daniel@xxxxxxxxxxxxx are queue-5.15/bpf-fix-kernel-address-leakage-in-atomic-fetch.patch queue-5.15/bpf-fix-kernel-address-leakage-in-atomic-cmpxchg-s-r0-aux-reg.patch queue-5.15/bpf-selftests-add-test-case-trying-to-taint-map-value-pointer.patch queue-5.15/bpf-selftests-add-test-case-for-atomic-fetch-on-spilled-pointer.patch queue-5.15/bpf-fix-signed-bounds-propagation-after-mov32.patch queue-5.15/bpf-selftests-update-test-case-for-atomic-cmpxchg-on-r0-with-pointer.patch queue-5.15/bpf-make-32-64-bounds-propagation-slightly-more-robust.patch