Skip to content

Commit f8f185e

Browse files
keeskuba-moo
authored andcommitted
net/mlx4_en: Introduce flexible array to silence overflow warning
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 <[email protected]> Link: https://lore.kernel.org/lkml/[email protected] Fixes: f68f2ff ("fortify: Detect struct member overflows in memcpy() at compile-time") Cc: Yishai Hadas <[email protected]> Signed-off-by: Kees Cook <[email protected]> Reviewed-by: Tariq Toukan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent be9832c commit f8f185e

File tree

2 files changed

+12
-11
lines changed
  • drivers/net/ethernet/mellanox/mlx4
  • include/linux/mlx4

2 files changed

+12
-11
lines changed

drivers/net/ethernet/mellanox/mlx4/en_tx.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -699,32 +699,32 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc,
699699
inl->byte_count = cpu_to_be32(1 << 31 | skb->len);
700700
} else {
701701
inl->byte_count = cpu_to_be32(1 << 31 | MIN_PKT_LEN);
702-
memset(((void *)(inl + 1)) + skb->len, 0,
702+
memset(inl->data + skb->len, 0,
703703
MIN_PKT_LEN - skb->len);
704704
}
705-
skb_copy_from_linear_data(skb, inl + 1, hlen);
705+
skb_copy_from_linear_data(skb, inl->data, hlen);
706706
if (shinfo->nr_frags)
707-
memcpy(((void *)(inl + 1)) + hlen, fragptr,
707+
memcpy(inl->data + hlen, fragptr,
708708
skb_frag_size(&shinfo->frags[0]));
709709

710710
} else {
711711
inl->byte_count = cpu_to_be32(1 << 31 | spc);
712712
if (hlen <= spc) {
713-
skb_copy_from_linear_data(skb, inl + 1, hlen);
713+
skb_copy_from_linear_data(skb, inl->data, hlen);
714714
if (hlen < spc) {
715-
memcpy(((void *)(inl + 1)) + hlen,
715+
memcpy(inl->data + hlen,
716716
fragptr, spc - hlen);
717717
fragptr += spc - hlen;
718718
}
719-
inl = (void *) (inl + 1) + spc;
720-
memcpy(((void *)(inl + 1)), fragptr, skb->len - spc);
719+
inl = (void *)inl->data + spc;
720+
memcpy(inl->data, fragptr, skb->len - spc);
721721
} else {
722-
skb_copy_from_linear_data(skb, inl + 1, spc);
723-
inl = (void *) (inl + 1) + spc;
724-
skb_copy_from_linear_data_offset(skb, spc, inl + 1,
722+
skb_copy_from_linear_data(skb, inl->data, spc);
723+
inl = (void *)inl->data + spc;
724+
skb_copy_from_linear_data_offset(skb, spc, inl->data,
725725
hlen - spc);
726726
if (shinfo->nr_frags)
727-
memcpy(((void *)(inl + 1)) + hlen - spc,
727+
memcpy(inl->data + hlen - spc,
728728
fragptr,
729729
skb_frag_size(&shinfo->frags[0]));
730730
}

include/linux/mlx4/qp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ enum {
446446

447447
struct mlx4_wqe_inline_seg {
448448
__be32 byte_count;
449+
__u8 data[];
449450
};
450451

451452
enum mlx4_update_qp_attr {

0 commit comments

Comments
 (0)