Patch "bpf: Fix truncation bug in coerce_reg_to_size_sx()" has been added to the 6.11-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    bpf: Fix truncation bug in coerce_reg_to_size_sx()

to the 6.11-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-fix-truncation-bug-in-coerce_reg_to_size_sx.patch
and it can be found in the queue-6.11 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 21cfd4e2edc6152d0c1638c154e300e280356f3f
Author: Dimitar Kanaliev <dimitar.kanaliev@xxxxxxxxxxxxxx>
Date:   Mon Oct 14 15:11:53 2024 +0300

    bpf: Fix truncation bug in coerce_reg_to_size_sx()
    
    [ Upstream commit ae67b9fb8c4e981e929a665dcaa070f4b05ebdb4 ]
    
    coerce_reg_to_size_sx() updates the register state after a sign-extension
    operation. However, there's a bug in the assignment order of the unsigned
    min/max values, leading to incorrect truncation:
    
      0: (85) call bpf_get_prandom_u32#7    ; R0_w=scalar()
      1: (57) r0 &= 1                       ; R0_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=1,var_off=(0x0; 0x1))
      2: (07) r0 += 254                     ; R0_w=scalar(smin=umin=smin32=umin32=254,smax=umax=smax32=umax32=255,var_off=(0xfe; 0x1))
      3: (bf) r0 = (s8)r0                   ; R0_w=scalar(smin=smin32=-2,smax=smax32=-1,umin=umin32=0xfffffffe,umax=0xffffffff,var_off=(0xfffffffffffffffe; 0x1))
    
    In the current implementation, the unsigned 32-bit min/max values
    (u32_min_value and u32_max_value) are assigned directly from the 64-bit
    signed min/max values (s64_min and s64_max):
    
      reg->umin_value = reg->u32_min_value = s64_min;
      reg->umax_value = reg->u32_max_value = s64_max;
    
    Due to the chain assigmnent, this is equivalent to:
    
      reg->u32_min_value = s64_min;  // Unintended truncation
      reg->umin_value = reg->u32_min_value;
      reg->u32_max_value = s64_max;  // Unintended truncation
      reg->umax_value = reg->u32_max_value;
    
    Fixes: 1f9a1ea821ff ("bpf: Support new sign-extension load insns")
    Reported-by: Shung-Hsi Yu <shung-hsi.yu@xxxxxxxx>
    Reported-by: Zac Ecob <zacecob@xxxxxxxxxxxxxx>
    Signed-off-by: Dimitar Kanaliev <dimitar.kanaliev@xxxxxxxxxxxxxx>
    Acked-by: Yonghong Song <yonghong.song@xxxxxxxxx>
    Reviewed-by: Shung-Hsi Yu <shung-hsi.yu@xxxxxxxx>
    Link: https://lore.kernel.org/r/20241014121155.92887-2-dimitar.kanaliev@xxxxxxxxxxxxxx
    Signed-off-by: Alexei Starovoitov <ast@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index a8d49b2b58e1e..42d6bc5392757 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -6255,10 +6255,10 @@ static void coerce_reg_to_size_sx(struct bpf_reg_state *reg, int size)
 
 	/* both of s64_max/s64_min positive or negative */
 	if ((s64_max >= 0) == (s64_min >= 0)) {
-		reg->smin_value = reg->s32_min_value = s64_min;
-		reg->smax_value = reg->s32_max_value = s64_max;
-		reg->umin_value = reg->u32_min_value = s64_min;
-		reg->umax_value = reg->u32_max_value = s64_max;
+		reg->s32_min_value = reg->smin_value = s64_min;
+		reg->s32_max_value = reg->smax_value = s64_max;
+		reg->u32_min_value = reg->umin_value = s64_min;
+		reg->u32_max_value = reg->umax_value = s64_max;
 		reg->var_off = tnum_range(s64_min, s64_max);
 		return;
 	}




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux