Skip to content

Commit 0d24201

Browse files
keesKalle Valo
authored andcommitted
wifi: iwlwifi: calib: Refactor iwl_calib_result usage for clarity
In preparation for FORTIFY_SOURCE performing run-time destination buffer bounds checking for memcpy(), refactor the use of struct iwl_calib_result: - Have struct iwl_calib_result contain struct iwl_calib_cmd since functions expect to operate on the "data" flex array in "cmd", which follows the "hdr" member. - Switch argument passing around to use struct iwl_calib_cmd instead of struct iwl_calib_hdr to prepare functions to see the "data" member. - Change iwl_calib_set()'s "len" argument to a size_t since it is always unsigned and is normally receiving the output of sizeof(). - Add an explicit length sanity check in iwl_calib_set(). - Adjust the memcpy() to avoid copying across the now visible composite flex array structure. This avoids the future run-time warning: memcpy: detected field-spanning write (size 8) of single field "&res->hdr" (size 4) Cc: Luca Coelho <[email protected]> Cc: Kalle Valo <[email protected]> Cc: "David S. Miller" <[email protected]> Cc: Jakub Kicinski <[email protected]> Cc: Lee Jones <[email protected]> Cc: Johannes Berg <[email protected]> Cc: [email protected] Cc: [email protected] Reported-by: Andy Lavr <[email protected]> Signed-off-by: Kees Cook <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b008f4a commit 0d24201

File tree

3 files changed

+17
-15
lines changed

3 files changed

+17
-15
lines changed

drivers/net/wireless/intel/iwlwifi/dvm/agn.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
112112
enum iwl_ucode_type ucode_type);
113113
int iwl_send_calib_results(struct iwl_priv *priv);
114114
int iwl_calib_set(struct iwl_priv *priv,
115-
const struct iwl_calib_hdr *cmd, int len);
115+
const struct iwl_calib_cmd *cmd, size_t len);
116116
void iwl_calib_free_results(struct iwl_priv *priv);
117117
int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
118118
char **buf);

drivers/net/wireless/intel/iwlwifi/dvm/calib.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
struct iwl_calib_result {
2020
struct list_head list;
2121
size_t cmd_len;
22-
struct iwl_calib_hdr hdr;
23-
/* data follows */
22+
struct iwl_calib_cmd cmd;
2423
};
2524

2625
struct statistics_general_data {
@@ -43,12 +42,12 @@ int iwl_send_calib_results(struct iwl_priv *priv)
4342
int ret;
4443

4544
hcmd.len[0] = res->cmd_len;
46-
hcmd.data[0] = &res->hdr;
45+
hcmd.data[0] = &res->cmd;
4746
hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
4847
ret = iwl_dvm_send_cmd(priv, &hcmd);
4948
if (ret) {
5049
IWL_ERR(priv, "Error %d on calib cmd %d\n",
51-
ret, res->hdr.op_code);
50+
ret, res->cmd.hdr.op_code);
5251
return ret;
5352
}
5453
}
@@ -57,19 +56,22 @@ int iwl_send_calib_results(struct iwl_priv *priv)
5756
}
5857

5958
int iwl_calib_set(struct iwl_priv *priv,
60-
const struct iwl_calib_hdr *cmd, int len)
59+
const struct iwl_calib_cmd *cmd, size_t len)
6160
{
6261
struct iwl_calib_result *res, *tmp;
6362

64-
res = kmalloc(sizeof(*res) + len - sizeof(struct iwl_calib_hdr),
65-
GFP_ATOMIC);
63+
if (check_sub_overflow(len, sizeof(*cmd), &len))
64+
return -ENOMEM;
65+
66+
res = kmalloc(struct_size(res, cmd.data, len), GFP_ATOMIC);
6667
if (!res)
6768
return -ENOMEM;
68-
memcpy(&res->hdr, cmd, len);
69-
res->cmd_len = len;
69+
res->cmd = *cmd;
70+
memcpy(res->cmd.data, cmd->data, len);
71+
res->cmd_len = struct_size(cmd, data, len);
7072

7173
list_for_each_entry(tmp, &priv->calib_results, list) {
72-
if (tmp->hdr.op_code == res->hdr.op_code) {
74+
if (tmp->cmd.hdr.op_code == res->cmd.hdr.op_code) {
7375
list_replace(&tmp->list, &res->list);
7476
kfree(tmp);
7577
return 0;

drivers/net/wireless/intel/iwlwifi/dvm/ucode.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -356,18 +356,18 @@ static bool iwlagn_wait_calib(struct iwl_notif_wait_data *notif_wait,
356356
struct iwl_rx_packet *pkt, void *data)
357357
{
358358
struct iwl_priv *priv = data;
359-
struct iwl_calib_hdr *hdr;
359+
struct iwl_calib_cmd *cmd;
360360

361361
if (pkt->hdr.cmd != CALIBRATION_RES_NOTIFICATION) {
362362
WARN_ON(pkt->hdr.cmd != CALIBRATION_COMPLETE_NOTIFICATION);
363363
return true;
364364
}
365365

366-
hdr = (struct iwl_calib_hdr *)pkt->data;
366+
cmd = (struct iwl_calib_cmd *)pkt->data;
367367

368-
if (iwl_calib_set(priv, hdr, iwl_rx_packet_payload_len(pkt)))
368+
if (iwl_calib_set(priv, cmd, iwl_rx_packet_payload_len(pkt)))
369369
IWL_ERR(priv, "Failed to record calibration data %d\n",
370-
hdr->op_code);
370+
cmd->hdr.op_code);
371371

372372
return false;
373373
}

0 commit comments

Comments
 (0)