mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-04 16:25:34 +00:00
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 <luciano.coelho@intel.com> Cc: Kalle Valo <kvalo@codeaurora.org> Cc: "David S. Miller" <davem@davemloft.net> Cc: Jakub Kicinski <kuba@kernel.org> Cc: Lee Jones <lee.jones@linaro.org> Cc: Johannes Berg <johannes.berg@intel.com> Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org Reported-by: Andy Lavr <andy.lavr@gmail.com> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20220901204558.2256458-1-keescook@chromium.org
This commit is contained in:
parent
b008f4a195
commit
0d24201f47
3 changed files with 17 additions and 15 deletions
|
@ -112,7 +112,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
|
|||
enum iwl_ucode_type ucode_type);
|
||||
int iwl_send_calib_results(struct iwl_priv *priv);
|
||||
int iwl_calib_set(struct iwl_priv *priv,
|
||||
const struct iwl_calib_hdr *cmd, int len);
|
||||
const struct iwl_calib_cmd *cmd, size_t len);
|
||||
void iwl_calib_free_results(struct iwl_priv *priv);
|
||||
int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
|
||||
char **buf);
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
struct iwl_calib_result {
|
||||
struct list_head list;
|
||||
size_t cmd_len;
|
||||
struct iwl_calib_hdr hdr;
|
||||
/* data follows */
|
||||
struct iwl_calib_cmd cmd;
|
||||
};
|
||||
|
||||
struct statistics_general_data {
|
||||
|
@ -43,12 +42,12 @@ int iwl_send_calib_results(struct iwl_priv *priv)
|
|||
int ret;
|
||||
|
||||
hcmd.len[0] = res->cmd_len;
|
||||
hcmd.data[0] = &res->hdr;
|
||||
hcmd.data[0] = &res->cmd;
|
||||
hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
|
||||
ret = iwl_dvm_send_cmd(priv, &hcmd);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Error %d on calib cmd %d\n",
|
||||
ret, res->hdr.op_code);
|
||||
ret, res->cmd.hdr.op_code);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -57,19 +56,22 @@ int iwl_send_calib_results(struct iwl_priv *priv)
|
|||
}
|
||||
|
||||
int iwl_calib_set(struct iwl_priv *priv,
|
||||
const struct iwl_calib_hdr *cmd, int len)
|
||||
const struct iwl_calib_cmd *cmd, size_t len)
|
||||
{
|
||||
struct iwl_calib_result *res, *tmp;
|
||||
|
||||
res = kmalloc(sizeof(*res) + len - sizeof(struct iwl_calib_hdr),
|
||||
GFP_ATOMIC);
|
||||
if (check_sub_overflow(len, sizeof(*cmd), &len))
|
||||
return -ENOMEM;
|
||||
|
||||
res = kmalloc(struct_size(res, cmd.data, len), GFP_ATOMIC);
|
||||
if (!res)
|
||||
return -ENOMEM;
|
||||
memcpy(&res->hdr, cmd, len);
|
||||
res->cmd_len = len;
|
||||
res->cmd = *cmd;
|
||||
memcpy(res->cmd.data, cmd->data, len);
|
||||
res->cmd_len = struct_size(cmd, data, len);
|
||||
|
||||
list_for_each_entry(tmp, &priv->calib_results, list) {
|
||||
if (tmp->hdr.op_code == res->hdr.op_code) {
|
||||
if (tmp->cmd.hdr.op_code == res->cmd.hdr.op_code) {
|
||||
list_replace(&tmp->list, &res->list);
|
||||
kfree(tmp);
|
||||
return 0;
|
||||
|
|
|
@ -356,18 +356,18 @@ static bool iwlagn_wait_calib(struct iwl_notif_wait_data *notif_wait,
|
|||
struct iwl_rx_packet *pkt, void *data)
|
||||
{
|
||||
struct iwl_priv *priv = data;
|
||||
struct iwl_calib_hdr *hdr;
|
||||
struct iwl_calib_cmd *cmd;
|
||||
|
||||
if (pkt->hdr.cmd != CALIBRATION_RES_NOTIFICATION) {
|
||||
WARN_ON(pkt->hdr.cmd != CALIBRATION_COMPLETE_NOTIFICATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
hdr = (struct iwl_calib_hdr *)pkt->data;
|
||||
cmd = (struct iwl_calib_cmd *)pkt->data;
|
||||
|
||||
if (iwl_calib_set(priv, hdr, iwl_rx_packet_payload_len(pkt)))
|
||||
if (iwl_calib_set(priv, cmd, iwl_rx_packet_payload_len(pkt)))
|
||||
IWL_ERR(priv, "Failed to record calibration data %d\n",
|
||||
hdr->op_code);
|
||||
cmd->hdr.op_code);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue