Skip to content

Commit ea9e148

Browse files
GustavoARSilvaVudentz
authored andcommitted
Bluetooth: hci_conn: Use __counted_by() and avoid -Wfamnae warning
Prepare for the coming implementation by GCC and Clang of the __counted_by attribute. Flexible array members annotated with __counted_by can have their accesses bounds-checked at run-time via CONFIG_UBSAN_BOUNDS (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family functions). Also, -Wflex-array-member-not-at-end is coming in GCC-14, and we are getting ready to enable it globally. So, use the `DEFINE_FLEX()` helper for an on-stack definition of a flexible structure where the size of the flexible-array member is known at compile-time, and refactor the rest of the code, accordingly. With these changes, fix the following warning: net/bluetooth/hci_conn.c:669:41: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] Link: KSPP/linux#202 Signed-off-by: Gustavo A. R. Silva <[email protected]> Reviewed-by: Kees Cook <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent 5c9f6a7 commit ea9e148

File tree

2 files changed

+17
-23
lines changed

2 files changed

+17
-23
lines changed

include/net/bluetooth/hci.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2143,7 +2143,7 @@ struct hci_cp_le_set_cig_params {
21432143
__le16 c_latency;
21442144
__le16 p_latency;
21452145
__u8 num_cis;
2146-
struct hci_cis_params cis[];
2146+
struct hci_cis_params cis[] __counted_by(num_cis);
21472147
} __packed;
21482148

21492149
struct hci_rp_le_set_cig_params {

net/bluetooth/hci_conn.c

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -664,11 +664,6 @@ static void le_conn_timeout(struct work_struct *work)
664664
hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
665665
}
666666

667-
struct iso_cig_params {
668-
struct hci_cp_le_set_cig_params cp;
669-
struct hci_cis_params cis[0x1f];
670-
};
671-
672667
struct iso_list_data {
673668
union {
674669
u8 cig;
@@ -1722,34 +1717,33 @@ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos)
17221717

17231718
static int set_cig_params_sync(struct hci_dev *hdev, void *data)
17241719
{
1720+
DEFINE_FLEX(struct hci_cp_le_set_cig_params, pdu, cis, num_cis, 0x1f);
17251721
u8 cig_id = PTR_UINT(data);
17261722
struct hci_conn *conn;
17271723
struct bt_iso_qos *qos;
1728-
struct iso_cig_params pdu;
1724+
u8 aux_num_cis = 0;
17291725
u8 cis_id;
17301726

17311727
conn = hci_conn_hash_lookup_cig(hdev, cig_id);
17321728
if (!conn)
17331729
return 0;
17341730

1735-
memset(&pdu, 0, sizeof(pdu));
1736-
17371731
qos = &conn->iso_qos;
1738-
pdu.cp.cig_id = cig_id;
1739-
hci_cpu_to_le24(qos->ucast.out.interval, pdu.cp.c_interval);
1740-
hci_cpu_to_le24(qos->ucast.in.interval, pdu.cp.p_interval);
1741-
pdu.cp.sca = qos->ucast.sca;
1742-
pdu.cp.packing = qos->ucast.packing;
1743-
pdu.cp.framing = qos->ucast.framing;
1744-
pdu.cp.c_latency = cpu_to_le16(qos->ucast.out.latency);
1745-
pdu.cp.p_latency = cpu_to_le16(qos->ucast.in.latency);
1732+
pdu->cig_id = cig_id;
1733+
hci_cpu_to_le24(qos->ucast.out.interval, pdu->c_interval);
1734+
hci_cpu_to_le24(qos->ucast.in.interval, pdu->p_interval);
1735+
pdu->sca = qos->ucast.sca;
1736+
pdu->packing = qos->ucast.packing;
1737+
pdu->framing = qos->ucast.framing;
1738+
pdu->c_latency = cpu_to_le16(qos->ucast.out.latency);
1739+
pdu->p_latency = cpu_to_le16(qos->ucast.in.latency);
17461740

17471741
/* Reprogram all CIS(s) with the same CIG, valid range are:
17481742
* num_cis: 0x00 to 0x1F
17491743
* cis_id: 0x00 to 0xEF
17501744
*/
17511745
for (cis_id = 0x00; cis_id < 0xf0 &&
1752-
pdu.cp.num_cis < ARRAY_SIZE(pdu.cis); cis_id++) {
1746+
aux_num_cis < pdu->num_cis; cis_id++) {
17531747
struct hci_cis_params *cis;
17541748

17551749
conn = hci_conn_hash_lookup_cis(hdev, NULL, 0, cig_id, cis_id);
@@ -1758,7 +1752,7 @@ static int set_cig_params_sync(struct hci_dev *hdev, void *data)
17581752

17591753
qos = &conn->iso_qos;
17601754

1761-
cis = &pdu.cis[pdu.cp.num_cis++];
1755+
cis = &pdu->cis[aux_num_cis++];
17621756
cis->cis_id = cis_id;
17631757
cis->c_sdu = cpu_to_le16(conn->iso_qos.ucast.out.sdu);
17641758
cis->p_sdu = cpu_to_le16(conn->iso_qos.ucast.in.sdu);
@@ -1769,14 +1763,14 @@ static int set_cig_params_sync(struct hci_dev *hdev, void *data)
17691763
cis->c_rtn = qos->ucast.out.rtn;
17701764
cis->p_rtn = qos->ucast.in.rtn;
17711765
}
1766+
pdu->num_cis = aux_num_cis;
17721767

1773-
if (!pdu.cp.num_cis)
1768+
if (!pdu->num_cis)
17741769
return 0;
17751770

17761771
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_CIG_PARAMS,
1777-
sizeof(pdu.cp) +
1778-
pdu.cp.num_cis * sizeof(pdu.cis[0]), &pdu,
1779-
HCI_CMD_TIMEOUT);
1772+
struct_size(pdu, cis, pdu->num_cis),
1773+
pdu, HCI_CMD_TIMEOUT);
17801774
}
17811775

17821776
static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)

0 commit comments

Comments
 (0)