mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 12:57:53 +00:00
Bluetooth: L2CAP: Avoid -Wflex-array-member-not-at-end warnings
-Wflex-array-member-not-at-end is coming in GCC-14, and we are getting ready to enable it globally. There are currently a couple of objects (`req` and `rsp`), in a couple of structures, that contain flexible structures (`struct l2cap_ecred_conn_req` and `struct l2cap_ecred_conn_rsp`), for example: struct l2cap_ecred_rsp_data { struct { struct l2cap_ecred_conn_rsp rsp; __le16 scid[L2CAP_ECRED_MAX_CID]; } __packed pdu; int count; }; in the struct above, `struct l2cap_ecred_conn_rsp` is a flexible structure: struct l2cap_ecred_conn_rsp { __le16 mtu; __le16 mps; __le16 credits; __le16 result; __le16 dcid[]; }; So, in order to avoid ending up with a flexible-array member in the middle of another structure, we use the `struct_group_tagged()` (and `__struct_group()` when the flexible structure is `__packed`) helper to separate the flexible array from the rest of the members in the flexible structure: struct l2cap_ecred_conn_rsp { struct_group_tagged(l2cap_ecred_conn_rsp_hdr, hdr, ... the rest of members ); __le16 dcid[]; }; With the change described above, we now declare objects of the type of the tagged struct, in this example `struct l2cap_ecred_conn_rsp_hdr`, without embedding flexible arrays in the middle of other structures: struct l2cap_ecred_rsp_data { struct { struct l2cap_ecred_conn_rsp_hdr rsp; __le16 scid[L2CAP_ECRED_MAX_CID]; } __packed pdu; int count; }; Also, when the flexible-array member needs to be accessed, we use `container_of()` to retrieve a pointer to the flexible structure. We also use the `DEFINE_RAW_FLEX()` helper for a couple of on-stack definitions of a flexible structure where the size of the flexible-array member is known at compile-time. So, with these changes, fix the following warnings: net/bluetooth/l2cap_core.c:1260:45: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] net/bluetooth/l2cap_core.c:3740:45: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] net/bluetooth/l2cap_core.c:4999:45: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] net/bluetooth/l2cap_core.c:7116:47: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] Link: https://github.com/KSPP/linux/issues/202 Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
62f7de372c
commit
1c08108f30
2 changed files with 35 additions and 33 deletions
|
@ -463,18 +463,24 @@ struct l2cap_le_credits {
|
||||||
#define L2CAP_ECRED_MAX_CID 5
|
#define L2CAP_ECRED_MAX_CID 5
|
||||||
|
|
||||||
struct l2cap_ecred_conn_req {
|
struct l2cap_ecred_conn_req {
|
||||||
__le16 psm;
|
/* New members must be added within the struct_group() macro below. */
|
||||||
__le16 mtu;
|
__struct_group(l2cap_ecred_conn_req_hdr, hdr, __packed,
|
||||||
__le16 mps;
|
__le16 psm;
|
||||||
__le16 credits;
|
__le16 mtu;
|
||||||
|
__le16 mps;
|
||||||
|
__le16 credits;
|
||||||
|
);
|
||||||
__le16 scid[];
|
__le16 scid[];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct l2cap_ecred_conn_rsp {
|
struct l2cap_ecred_conn_rsp {
|
||||||
__le16 mtu;
|
/* New members must be added within the struct_group() macro below. */
|
||||||
__le16 mps;
|
struct_group_tagged(l2cap_ecred_conn_rsp_hdr, hdr,
|
||||||
__le16 credits;
|
__le16 mtu;
|
||||||
__le16 result;
|
__le16 mps;
|
||||||
|
__le16 credits;
|
||||||
|
__le16 result;
|
||||||
|
);
|
||||||
__le16 dcid[];
|
__le16 dcid[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1260,7 +1260,7 @@ static void l2cap_le_connect(struct l2cap_chan *chan)
|
||||||
|
|
||||||
struct l2cap_ecred_conn_data {
|
struct l2cap_ecred_conn_data {
|
||||||
struct {
|
struct {
|
||||||
struct l2cap_ecred_conn_req req;
|
struct l2cap_ecred_conn_req_hdr req;
|
||||||
__le16 scid[5];
|
__le16 scid[5];
|
||||||
} __packed pdu;
|
} __packed pdu;
|
||||||
struct l2cap_chan *chan;
|
struct l2cap_chan *chan;
|
||||||
|
@ -3740,7 +3740,7 @@ static void l2cap_ecred_list_defer(struct l2cap_chan *chan, void *data)
|
||||||
|
|
||||||
struct l2cap_ecred_rsp_data {
|
struct l2cap_ecred_rsp_data {
|
||||||
struct {
|
struct {
|
||||||
struct l2cap_ecred_conn_rsp rsp;
|
struct l2cap_ecred_conn_rsp_hdr rsp;
|
||||||
__le16 scid[L2CAP_ECRED_MAX_CID];
|
__le16 scid[L2CAP_ECRED_MAX_CID];
|
||||||
} __packed pdu;
|
} __packed pdu;
|
||||||
int count;
|
int count;
|
||||||
|
@ -3749,6 +3749,8 @@ struct l2cap_ecred_rsp_data {
|
||||||
static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
|
static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
|
||||||
{
|
{
|
||||||
struct l2cap_ecred_rsp_data *rsp = data;
|
struct l2cap_ecred_rsp_data *rsp = data;
|
||||||
|
struct l2cap_ecred_conn_rsp *rsp_flex =
|
||||||
|
container_of(&rsp->pdu.rsp, struct l2cap_ecred_conn_rsp, hdr);
|
||||||
|
|
||||||
if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
|
if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
|
||||||
return;
|
return;
|
||||||
|
@ -3758,7 +3760,7 @@ static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
|
||||||
|
|
||||||
/* Include all channels pending with the same ident */
|
/* Include all channels pending with the same ident */
|
||||||
if (!rsp->pdu.rsp.result)
|
if (!rsp->pdu.rsp.result)
|
||||||
rsp->pdu.rsp.dcid[rsp->count++] = cpu_to_le16(chan->scid);
|
rsp_flex->dcid[rsp->count++] = cpu_to_le16(chan->scid);
|
||||||
else
|
else
|
||||||
l2cap_chan_del(chan, ECONNRESET);
|
l2cap_chan_del(chan, ECONNRESET);
|
||||||
}
|
}
|
||||||
|
@ -4996,10 +4998,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
|
||||||
u8 *data)
|
u8 *data)
|
||||||
{
|
{
|
||||||
struct l2cap_ecred_conn_req *req = (void *) data;
|
struct l2cap_ecred_conn_req *req = (void *) data;
|
||||||
struct {
|
DEFINE_RAW_FLEX(struct l2cap_ecred_conn_rsp, pdu, dcid, L2CAP_ECRED_MAX_CID);
|
||||||
struct l2cap_ecred_conn_rsp rsp;
|
|
||||||
__le16 dcid[L2CAP_ECRED_MAX_CID];
|
|
||||||
} __packed pdu;
|
|
||||||
struct l2cap_chan *chan, *pchan;
|
struct l2cap_chan *chan, *pchan;
|
||||||
u16 mtu, mps;
|
u16 mtu, mps;
|
||||||
__le16 psm;
|
__le16 psm;
|
||||||
|
@ -5018,7 +5017,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
|
||||||
cmd_len -= sizeof(*req);
|
cmd_len -= sizeof(*req);
|
||||||
num_scid = cmd_len / sizeof(u16);
|
num_scid = cmd_len / sizeof(u16);
|
||||||
|
|
||||||
if (num_scid > ARRAY_SIZE(pdu.dcid)) {
|
if (num_scid > L2CAP_ECRED_MAX_CID) {
|
||||||
result = L2CAP_CR_LE_INVALID_PARAMS;
|
result = L2CAP_CR_LE_INVALID_PARAMS;
|
||||||
goto response;
|
goto response;
|
||||||
}
|
}
|
||||||
|
@ -5047,7 +5046,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
|
||||||
|
|
||||||
BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps);
|
BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps);
|
||||||
|
|
||||||
memset(&pdu, 0, sizeof(pdu));
|
memset(pdu, 0, sizeof(*pdu));
|
||||||
|
|
||||||
/* Check if we have socket listening on psm */
|
/* Check if we have socket listening on psm */
|
||||||
pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
|
pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
|
||||||
|
@ -5073,8 +5072,8 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
|
||||||
|
|
||||||
BT_DBG("scid[%d] 0x%4.4x", i, scid);
|
BT_DBG("scid[%d] 0x%4.4x", i, scid);
|
||||||
|
|
||||||
pdu.dcid[i] = 0x0000;
|
pdu->dcid[i] = 0x0000;
|
||||||
len += sizeof(*pdu.dcid);
|
len += sizeof(*pdu->dcid);
|
||||||
|
|
||||||
/* Check for valid dynamic CID range */
|
/* Check for valid dynamic CID range */
|
||||||
if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) {
|
if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) {
|
||||||
|
@ -5108,13 +5107,13 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
|
||||||
l2cap_ecred_init(chan, __le16_to_cpu(req->credits));
|
l2cap_ecred_init(chan, __le16_to_cpu(req->credits));
|
||||||
|
|
||||||
/* Init response */
|
/* Init response */
|
||||||
if (!pdu.rsp.credits) {
|
if (!pdu->credits) {
|
||||||
pdu.rsp.mtu = cpu_to_le16(chan->imtu);
|
pdu->mtu = cpu_to_le16(chan->imtu);
|
||||||
pdu.rsp.mps = cpu_to_le16(chan->mps);
|
pdu->mps = cpu_to_le16(chan->mps);
|
||||||
pdu.rsp.credits = cpu_to_le16(chan->rx_credits);
|
pdu->credits = cpu_to_le16(chan->rx_credits);
|
||||||
}
|
}
|
||||||
|
|
||||||
pdu.dcid[i] = cpu_to_le16(chan->scid);
|
pdu->dcid[i] = cpu_to_le16(chan->scid);
|
||||||
|
|
||||||
__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
|
__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
|
||||||
|
|
||||||
|
@ -5136,13 +5135,13 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
|
||||||
l2cap_chan_put(pchan);
|
l2cap_chan_put(pchan);
|
||||||
|
|
||||||
response:
|
response:
|
||||||
pdu.rsp.result = cpu_to_le16(result);
|
pdu->result = cpu_to_le16(result);
|
||||||
|
|
||||||
if (defer)
|
if (defer)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
l2cap_send_cmd(conn, cmd->ident, L2CAP_ECRED_CONN_RSP,
|
l2cap_send_cmd(conn, cmd->ident, L2CAP_ECRED_CONN_RSP,
|
||||||
sizeof(pdu.rsp) + len, &pdu);
|
sizeof(*pdu) + len, pdu);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -7113,14 +7112,11 @@ EXPORT_SYMBOL_GPL(l2cap_chan_connect);
|
||||||
static void l2cap_ecred_reconfigure(struct l2cap_chan *chan)
|
static void l2cap_ecred_reconfigure(struct l2cap_chan *chan)
|
||||||
{
|
{
|
||||||
struct l2cap_conn *conn = chan->conn;
|
struct l2cap_conn *conn = chan->conn;
|
||||||
struct {
|
DEFINE_RAW_FLEX(struct l2cap_ecred_reconf_req, pdu, scid, 1);
|
||||||
struct l2cap_ecred_reconf_req req;
|
|
||||||
__le16 scid;
|
|
||||||
} pdu;
|
|
||||||
|
|
||||||
pdu.req.mtu = cpu_to_le16(chan->imtu);
|
pdu->mtu = cpu_to_le16(chan->imtu);
|
||||||
pdu.req.mps = cpu_to_le16(chan->mps);
|
pdu->mps = cpu_to_le16(chan->mps);
|
||||||
pdu.scid = cpu_to_le16(chan->scid);
|
pdu->scid[0] = cpu_to_le16(chan->scid);
|
||||||
|
|
||||||
chan->ident = l2cap_get_ident(conn);
|
chan->ident = l2cap_get_ident(conn);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue