Commit ea9e148c authored by Gustavo A. R. Silva's avatar Gustavo A. R. Silva Committed by Luiz Augusto von Dentz

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: https://github.com/KSPP/linux/issues/202Signed-off-by: default avatarGustavo A. R. Silva <gustavoars@kernel.org>
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 5c9f6a78
...@@ -2143,7 +2143,7 @@ struct hci_cp_le_set_cig_params { ...@@ -2143,7 +2143,7 @@ struct hci_cp_le_set_cig_params {
__le16 c_latency; __le16 c_latency;
__le16 p_latency; __le16 p_latency;
__u8 num_cis; __u8 num_cis;
struct hci_cis_params cis[]; struct hci_cis_params cis[] __counted_by(num_cis);
} __packed; } __packed;
struct hci_rp_le_set_cig_params { struct hci_rp_le_set_cig_params {
......
...@@ -664,11 +664,6 @@ static void le_conn_timeout(struct work_struct *work) ...@@ -664,11 +664,6 @@ static void le_conn_timeout(struct work_struct *work)
hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM); hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
} }
struct iso_cig_params {
struct hci_cp_le_set_cig_params cp;
struct hci_cis_params cis[0x1f];
};
struct iso_list_data { struct iso_list_data {
union { union {
u8 cig; u8 cig;
...@@ -1722,34 +1717,33 @@ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos) ...@@ -1722,34 +1717,33 @@ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos)
static int set_cig_params_sync(struct hci_dev *hdev, void *data) static int set_cig_params_sync(struct hci_dev *hdev, void *data)
{ {
DEFINE_FLEX(struct hci_cp_le_set_cig_params, pdu, cis, num_cis, 0x1f);
u8 cig_id = PTR_UINT(data); u8 cig_id = PTR_UINT(data);
struct hci_conn *conn; struct hci_conn *conn;
struct bt_iso_qos *qos; struct bt_iso_qos *qos;
struct iso_cig_params pdu; u8 aux_num_cis = 0;
u8 cis_id; u8 cis_id;
conn = hci_conn_hash_lookup_cig(hdev, cig_id); conn = hci_conn_hash_lookup_cig(hdev, cig_id);
if (!conn) if (!conn)
return 0; return 0;
memset(&pdu, 0, sizeof(pdu));
qos = &conn->iso_qos; qos = &conn->iso_qos;
pdu.cp.cig_id = cig_id; pdu->cig_id = cig_id;
hci_cpu_to_le24(qos->ucast.out.interval, pdu.cp.c_interval); hci_cpu_to_le24(qos->ucast.out.interval, pdu->c_interval);
hci_cpu_to_le24(qos->ucast.in.interval, pdu.cp.p_interval); hci_cpu_to_le24(qos->ucast.in.interval, pdu->p_interval);
pdu.cp.sca = qos->ucast.sca; pdu->sca = qos->ucast.sca;
pdu.cp.packing = qos->ucast.packing; pdu->packing = qos->ucast.packing;
pdu.cp.framing = qos->ucast.framing; pdu->framing = qos->ucast.framing;
pdu.cp.c_latency = cpu_to_le16(qos->ucast.out.latency); pdu->c_latency = cpu_to_le16(qos->ucast.out.latency);
pdu.cp.p_latency = cpu_to_le16(qos->ucast.in.latency); pdu->p_latency = cpu_to_le16(qos->ucast.in.latency);
/* Reprogram all CIS(s) with the same CIG, valid range are: /* Reprogram all CIS(s) with the same CIG, valid range are:
* num_cis: 0x00 to 0x1F * num_cis: 0x00 to 0x1F
* cis_id: 0x00 to 0xEF * cis_id: 0x00 to 0xEF
*/ */
for (cis_id = 0x00; cis_id < 0xf0 && for (cis_id = 0x00; cis_id < 0xf0 &&
pdu.cp.num_cis < ARRAY_SIZE(pdu.cis); cis_id++) { aux_num_cis < pdu->num_cis; cis_id++) {
struct hci_cis_params *cis; struct hci_cis_params *cis;
conn = hci_conn_hash_lookup_cis(hdev, NULL, 0, cig_id, cis_id); 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) ...@@ -1758,7 +1752,7 @@ static int set_cig_params_sync(struct hci_dev *hdev, void *data)
qos = &conn->iso_qos; qos = &conn->iso_qos;
cis = &pdu.cis[pdu.cp.num_cis++]; cis = &pdu->cis[aux_num_cis++];
cis->cis_id = cis_id; cis->cis_id = cis_id;
cis->c_sdu = cpu_to_le16(conn->iso_qos.ucast.out.sdu); cis->c_sdu = cpu_to_le16(conn->iso_qos.ucast.out.sdu);
cis->p_sdu = cpu_to_le16(conn->iso_qos.ucast.in.sdu); 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) ...@@ -1769,14 +1763,14 @@ static int set_cig_params_sync(struct hci_dev *hdev, void *data)
cis->c_rtn = qos->ucast.out.rtn; cis->c_rtn = qos->ucast.out.rtn;
cis->p_rtn = qos->ucast.in.rtn; cis->p_rtn = qos->ucast.in.rtn;
} }
pdu->num_cis = aux_num_cis;
if (!pdu.cp.num_cis) if (!pdu->num_cis)
return 0; return 0;
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_CIG_PARAMS, return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_CIG_PARAMS,
sizeof(pdu.cp) + struct_size(pdu, cis, pdu->num_cis),
pdu.cp.num_cis * sizeof(pdu.cis[0]), &pdu, pdu, HCI_CMD_TIMEOUT);
HCI_CMD_TIMEOUT);
} }
static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos) static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment