Skip to content

Commit c1ddb29

Browse files
GustavoARSilvaandersson
authored andcommitted
rpmsg: glink: Avoid -Wflex-array-member-not-at-end warnings
-Wflex-array-member-not-at-end was introduced in GCC-14, and we are getting ready to enable it, globally. So, in order to avoid ending up with a flexible-array member in the middle of multiple other structs, we use the `__struct_group()` helper to create a new tagged `struct glink_msg_hdr`. This structure groups together all the members of the flexible `struct glink_msg` except the flexible array. As a result, the array is effectively separated from the rest of the members without modifying the memory layout of the flexible structure. We then change the type of the middle struct members currently causing trouble from `struct glink_msg` to `struct glink_msg_hdr`. We also want to ensure that when new members need to be added to the flexible structure, they are always included within the newly created tagged struct. For this, we use `static_assert()`. This ensures that the memory layout for both the flexible structure and the new tagged struct is the same after any changes. This approach avoids having to implement `struct glink_msg_hdr` as a completely separate structure, thus preventing having to maintain two independent but basically identical structures, closing the door to potential bugs in the future. We also use `container_of()` whenever we need to retrieve a pointer to the flexible structure, through which we can access the flexible-array member, if necessary. Additionally, we use the `DEFINE_RAW_FLEX()` helper for an on-stack definition of a flexible structure where the size for the flexible-array member is known at compile-time. So, with these changes, fix the following warnings: drivers/rpmsg/qcom_glink_native.c:51:26: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/rpmsg/qcom_glink_native.c:459:34: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/rpmsg/qcom_glink_native.c:846:34: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/rpmsg/qcom_glink_native.c:968:34: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/rpmsg/qcom_glink_native.c:1380:34: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org> Reviewed-by: Kees Cook <kees@kernel.org> Link: https://lore.kernel.org/r/ZrOQa2gew5yadyt3@cute Signed-off-by: Bjorn Andersson <andersson@kernel.org>
1 parent 34f79c1 commit c1ddb29

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

drivers/rpmsg/qcom_glink_native.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,16 @@
3333
#define RPM_GLINK_CID_MAX 65536
3434

3535
struct glink_msg {
36-
__le16 cmd;
37-
__le16 param1;
38-
__le32 param2;
36+
/* New members MUST be added within the __struct_group() macro below. */
37+
__struct_group(glink_msg_hdr, hdr, __packed,
38+
__le16 cmd;
39+
__le16 param1;
40+
__le32 param2;
41+
);
3942
u8 data[];
4043
} __packed;
44+
static_assert(offsetof(struct glink_msg, data) == sizeof(struct glink_msg_hdr),
45+
"struct member likely outside of __struct_group()");
4146

4247
/**
4348
* struct glink_defer_cmd - deferred incoming control message
@@ -51,7 +56,7 @@ struct glink_msg {
5156
struct glink_defer_cmd {
5257
struct list_head node;
5358

54-
struct glink_msg msg;
59+
struct glink_msg_hdr msg;
5560
u8 data[];
5661
};
5762

@@ -475,12 +480,9 @@ static void qcom_glink_intent_req_abort(struct glink_channel *channel)
475480
static int qcom_glink_send_open_req(struct qcom_glink *glink,
476481
struct glink_channel *channel)
477482
{
478-
struct {
479-
struct glink_msg msg;
480-
u8 name[GLINK_NAME_SIZE];
481-
} __packed req;
483+
DEFINE_RAW_FLEX(struct glink_msg, req, data, GLINK_NAME_SIZE);
482484
int name_len = strlen(channel->name) + 1;
483-
int req_len = ALIGN(sizeof(req.msg) + name_len, 8);
485+
int req_len = ALIGN(sizeof(*req) + name_len, 8);
484486
int ret;
485487
unsigned long flags;
486488

@@ -496,15 +498,15 @@ static int qcom_glink_send_open_req(struct qcom_glink *glink,
496498

497499
channel->lcid = ret;
498500

499-
req.msg.cmd = cpu_to_le16(GLINK_CMD_OPEN);
500-
req.msg.param1 = cpu_to_le16(channel->lcid);
501-
req.msg.param2 = cpu_to_le32(name_len);
502-
strcpy(req.name, channel->name);
501+
req->cmd = cpu_to_le16(GLINK_CMD_OPEN);
502+
req->param1 = cpu_to_le16(channel->lcid);
503+
req->param2 = cpu_to_le32(name_len);
504+
strcpy(req->data, channel->name);
503505

504506
trace_qcom_glink_cmd_open_tx(glink->label, channel->name,
505507
channel->lcid, channel->rcid);
506508

507-
ret = qcom_glink_tx(glink, &req, req_len, NULL, 0, true);
509+
ret = qcom_glink_tx(glink, req, req_len, NULL, 0, true);
508510
if (ret)
509511
goto remove_idr;
510512

@@ -879,7 +881,9 @@ static int qcom_glink_rx_defer(struct qcom_glink *glink, size_t extra)
879881

880882
INIT_LIST_HEAD(&dcmd->node);
881883

882-
qcom_glink_rx_peek(glink, &dcmd->msg, 0, sizeof(dcmd->msg) + extra);
884+
qcom_glink_rx_peek(glink,
885+
container_of(&dcmd->msg, struct glink_msg, hdr), 0,
886+
sizeof(dcmd->msg) + extra);
883887

884888
spin_lock(&glink->rx_lock);
885889
list_add_tail(&dcmd->node, &glink->rx_queue);
@@ -896,7 +900,7 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
896900
struct glink_core_rx_intent *intent;
897901
struct glink_channel *channel;
898902
struct {
899-
struct glink_msg msg;
903+
struct glink_msg_hdr msg;
900904
__le32 chunk_size;
901905
__le32 left_size;
902906
} __packed hdr;
@@ -1030,7 +1034,7 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
10301034
};
10311035

10321036
struct {
1033-
struct glink_msg msg;
1037+
struct glink_msg_hdr msg;
10341038
struct intent_pair intents[];
10351039
} __packed * msg;
10361040

@@ -1459,7 +1463,7 @@ static int __qcom_glink_send(struct glink_channel *channel,
14591463
struct glink_core_rx_intent *tmp;
14601464
int iid = 0;
14611465
struct {
1462-
struct glink_msg msg;
1466+
struct glink_msg_hdr msg;
14631467
__le32 chunk_size;
14641468
__le32 left_size;
14651469
} __packed req;
@@ -1781,7 +1785,7 @@ static void qcom_glink_work(struct work_struct *work)
17811785
list_del(&dcmd->node);
17821786
spin_unlock_irqrestore(&glink->rx_lock, flags);
17831787

1784-
msg = &dcmd->msg;
1788+
msg = container_of(&dcmd->msg, struct glink_msg, hdr);
17851789
cmd = le16_to_cpu(msg->cmd);
17861790
param1 = le16_to_cpu(msg->param1);
17871791
param2 = le32_to_cpu(msg->param2);

0 commit comments

Comments
 (0)