Skip to content

Commit aa4d540

Browse files
GustavoARSilvarleon
authored andcommitted
RDMA/core: Fix multiple -Warray-bounds warnings
GCC-13 (and Clang)[1] does not like to access a partially allocated object, since it cannot reason about it for bounds checking. In this case 140 bytes are allocated for an object of type struct ib_umad_packet: packet = kzalloc(sizeof(*packet) + IB_MGMT_RMPP_HDR, GFP_KERNEL); However, notice that sizeof(*packet) is only 104 bytes: struct ib_umad_packet { struct ib_mad_send_buf * msg; /* 0 8 */ struct ib_mad_recv_wc * recv_wc; /* 8 8 */ struct list_head list; /* 16 16 */ int length; /* 32 4 */ /* XXX 4 bytes hole, try to pack */ struct ib_user_mad mad __attribute__((__aligned__(8))); /* 40 64 */ /* size: 104, cachelines: 2, members: 5 */ /* sum members: 100, holes: 1, sum holes: 4 */ /* forced alignments: 1, forced holes: 1, sum forced holes: 4 */ /* last cacheline: 40 bytes */ } __attribute__((__aligned__(8))); and 36 bytes extra bytes are allocated for a flexible-array member in struct ib_user_mad: include/rdma/ib_mad.h: 120 enum { ... 123 IB_MGMT_RMPP_HDR = 36, ... } struct ib_user_mad { struct ib_user_mad_hdr hdr; /* 0 64 */ /* --- cacheline 1 boundary (64 bytes) --- */ __u64 data[] __attribute__((__aligned__(8))); /* 64 0 */ /* size: 64, cachelines: 1, members: 2 */ /* forced alignments: 1 */ } __attribute__((__aligned__(8))); So we have sizeof(*packet) + IB_MGMT_RMPP_HDR == 140 bytes Then the address of the flex-array member (for which only 36 bytes were allocated) is casted and copied into a pointer to struct ib_rmpp_mad, which, in turn, is of size 256 bytes: rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; struct ib_rmpp_mad { struct ib_mad_hdr mad_hdr; /* 0 24 */ struct ib_rmpp_hdr rmpp_hdr; /* 24 12 */ u8 data[220]; /* 36 220 */ /* size: 256, cachelines: 4, members: 3 */ }; The thing is that those 36 bytes allocated for flex-array member data in struct ib_user_mad onlly account for the size of both struct ib_mad_hdr and struct ib_rmpp_hdr, but nothing is left for array u8 data[220]. So, the compiler is legitimately complaining about accessing an object for which not enough memory was allocated. Apparently, the only members of struct ib_rmpp_mad that are relevant (that are actually being used) in function ib_umad_write() are mad_hdr and rmpp_hdr. So, instead of casting packet->mad.data to (struct ib_rmpp_mad *) create a new structure struct ib_rmpp_mad_hdr { struct ib_mad_hdr mad_hdr; struct ib_rmpp_hdr rmpp_hdr; } __packed; and cast packet->mad.data to (struct ib_rmpp_mad_hdr *). Notice that IB_MGMT_RMPP_HDR == sizeof(struct ib_rmpp_mad_hdr) == 36 bytes Refactor the rest of the code, accordingly. Fix the following warnings seen under GCC-13 and -Warray-bounds: drivers/infiniband/core/user_mad.c:564:50: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=] drivers/infiniband/core/user_mad.c:566:42: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=] drivers/infiniband/core/user_mad.c:618:25: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=] drivers/infiniband/core/user_mad.c:622:44: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=] Link: KSPP/linux#273 Link: https://godbolt.org/z/oYWaGM4Yb [1] Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org> Link: https://lore.kernel.org/r/ZBpB91qQcB10m3Fw@work Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent 602fb42 commit aa4d540

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

drivers/infiniband/core/user_mad.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ struct ib_umad_packet {
131131
struct ib_user_mad mad;
132132
};
133133

134+
struct ib_rmpp_mad_hdr {
135+
struct ib_mad_hdr mad_hdr;
136+
struct ib_rmpp_hdr rmpp_hdr;
137+
} __packed;
138+
134139
#define CREATE_TRACE_POINTS
135140
#include <trace/events/ib_umad.h>
136141

@@ -494,19 +499,19 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
494499
size_t count, loff_t *pos)
495500
{
496501
struct ib_umad_file *file = filp->private_data;
502+
struct ib_rmpp_mad_hdr *rmpp_mad_hdr;
497503
struct ib_umad_packet *packet;
498504
struct ib_mad_agent *agent;
499505
struct rdma_ah_attr ah_attr;
500506
struct ib_ah *ah;
501-
struct ib_rmpp_mad *rmpp_mad;
502507
__be64 *tid;
503508
int ret, data_len, hdr_len, copy_offset, rmpp_active;
504509
u8 base_version;
505510

506511
if (count < hdr_size(file) + IB_MGMT_RMPP_HDR)
507512
return -EINVAL;
508513

509-
packet = kzalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL);
514+
packet = kzalloc(sizeof(*packet) + IB_MGMT_RMPP_HDR, GFP_KERNEL);
510515
if (!packet)
511516
return -ENOMEM;
512517

@@ -560,13 +565,13 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
560565
goto err_up;
561566
}
562567

563-
rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data;
564-
hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class);
568+
rmpp_mad_hdr = (struct ib_rmpp_mad_hdr *)packet->mad.data;
569+
hdr_len = ib_get_mad_data_offset(rmpp_mad_hdr->mad_hdr.mgmt_class);
565570

566-
if (ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)
571+
if (ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class)
567572
&& ib_mad_kernel_rmpp_agent(agent)) {
568573
copy_offset = IB_MGMT_RMPP_HDR;
569-
rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
574+
rmpp_active = ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) &
570575
IB_MGMT_RMPP_FLAG_ACTIVE;
571576
} else {
572577
copy_offset = IB_MGMT_MAD_HDR;
@@ -615,12 +620,12 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
615620
tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid;
616621
*tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
617622
(be64_to_cpup(tid) & 0xffffffff));
618-
rmpp_mad->mad_hdr.tid = *tid;
623+
rmpp_mad_hdr->mad_hdr.tid = *tid;
619624
}
620625

621626
if (!ib_mad_kernel_rmpp_agent(agent)
622-
&& ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)
623-
&& (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) {
627+
&& ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class)
628+
&& (ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) {
624629
spin_lock_irq(&file->send_lock);
625630
list_add_tail(&packet->list, &file->send_list);
626631
spin_unlock_irq(&file->send_lock);

0 commit comments

Comments
 (0)