Patch "net/mlx4_en: Introduce flexible array to silence overflow warning" has been added to the 6.2-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

    net/mlx4_en: Introduce flexible array to silence overflow warning

to the 6.2-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:
     net-mlx4_en-introduce-flexible-array-to-silence-over.patch
and it can be found in the queue-6.2 subdirectory.

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



commit 6bf59a3bd623a3c91322cd835b10586acac2ac91
Author: Kees Cook <keescook@xxxxxxxxxxxx>
Date:   Sat Feb 18 10:38:50 2023 -0800

    net/mlx4_en: Introduce flexible array to silence overflow warning
    
    [ Upstream commit f8f185e39b4de91bc5235e5be0d829bea69d9b06 ]
    
    The call "skb_copy_from_linear_data(skb, inl + 1, spc)" triggers a FORTIFY
    memcpy() warning on ppc64 platform:
    
    In function ‘fortify_memcpy_chk’,
        inlined from ‘skb_copy_from_linear_data’ at ./include/linux/skbuff.h:4029:2,
        inlined from ‘build_inline_wqe’ at drivers/net/ethernet/mellanox/mlx4/en_tx.c:722:4,
        inlined from ‘mlx4_en_xmit’ at drivers/net/ethernet/mellanox/mlx4/en_tx.c:1066:3:
    ./include/linux/fortify-string.h:513:25: error: call to ‘__write_overflow_field’ declared with
    attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()?
    [-Werror=attribute-warning]
      513 |                         __write_overflow_field(p_size_field, size);
          |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    Same behaviour on x86 you can get if you use "__always_inline" instead of
    "inline" for skb_copy_from_linear_data() in skbuff.h
    
    The call here copies data into inlined tx destricptor, which has 104
    bytes (MAX_INLINE) space for data payload. In this case "spc" is known
    in compile-time but the destination is used with hidden knowledge
    (real structure of destination is different from that the compiler
    can see). That cause the fortify warning because compiler can check
    bounds, but the real bounds are different.  "spc" can't be bigger than
    64 bytes (MLX4_INLINE_ALIGN), so the data can always fit into inlined
    tx descriptor. The fact that "inl" points into inlined tx descriptor is
    determined earlier in mlx4_en_xmit().
    
    Avoid confusing the compiler with "inl + 1" constructions to get to past
    the inl header by introducing a flexible array "data" to the struct so
    that the compiler can see that we are not dealing with an array of inl
    structs, but rather, arbitrary data following the structure. There are
    no changes to the structure layout reported by pahole, and the resulting
    machine code is actually smaller.
    
    Reported-by: Josef Oskera <joskera@xxxxxxxxxx>
    Link: https://lore.kernel.org/lkml/20230217094541.2362873-1-joskera@xxxxxxxxxx
    Fixes: f68f2ff91512 ("fortify: Detect struct member overflows in memcpy() at compile-time")
    Cc: Yishai Hadas <yishaih@xxxxxxxxxx>
    Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx>
    Reviewed-by: Tariq Toukan <tariqt@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20230218183842.never.954-kees@xxxxxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index c5758637b7bed..2f79378fbf6ec 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -699,32 +699,32 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc,
 			inl->byte_count = cpu_to_be32(1 << 31 | skb->len);
 		} else {
 			inl->byte_count = cpu_to_be32(1 << 31 | MIN_PKT_LEN);
-			memset(((void *)(inl + 1)) + skb->len, 0,
+			memset(inl->data + skb->len, 0,
 			       MIN_PKT_LEN - skb->len);
 		}
-		skb_copy_from_linear_data(skb, inl + 1, hlen);
+		skb_copy_from_linear_data(skb, inl->data, hlen);
 		if (shinfo->nr_frags)
-			memcpy(((void *)(inl + 1)) + hlen, fragptr,
+			memcpy(inl->data + hlen, fragptr,
 			       skb_frag_size(&shinfo->frags[0]));
 
 	} else {
 		inl->byte_count = cpu_to_be32(1 << 31 | spc);
 		if (hlen <= spc) {
-			skb_copy_from_linear_data(skb, inl + 1, hlen);
+			skb_copy_from_linear_data(skb, inl->data, hlen);
 			if (hlen < spc) {
-				memcpy(((void *)(inl + 1)) + hlen,
+				memcpy(inl->data + hlen,
 				       fragptr, spc - hlen);
 				fragptr +=  spc - hlen;
 			}
-			inl = (void *) (inl + 1) + spc;
-			memcpy(((void *)(inl + 1)), fragptr, skb->len - spc);
+			inl = (void *)inl->data + spc;
+			memcpy(inl->data, fragptr, skb->len - spc);
 		} else {
-			skb_copy_from_linear_data(skb, inl + 1, spc);
-			inl = (void *) (inl + 1) + spc;
-			skb_copy_from_linear_data_offset(skb, spc, inl + 1,
+			skb_copy_from_linear_data(skb, inl->data, spc);
+			inl = (void *)inl->data + spc;
+			skb_copy_from_linear_data_offset(skb, spc, inl->data,
 							 hlen - spc);
 			if (shinfo->nr_frags)
-				memcpy(((void *)(inl + 1)) + hlen - spc,
+				memcpy(inl->data + hlen - spc,
 				       fragptr,
 				       skb_frag_size(&shinfo->frags[0]));
 		}
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
index 9db93e487496a..b6b626157b03a 100644
--- a/include/linux/mlx4/qp.h
+++ b/include/linux/mlx4/qp.h
@@ -446,6 +446,7 @@ enum {
 
 struct mlx4_wqe_inline_seg {
 	__be32			byte_count;
+	__u8			data[];
 };
 
 enum mlx4_update_qp_attr {



[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