summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlegacy/common.c
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2024-09-12 01:01:21 +0200
committerKalle Valo <kvalo@kernel.org>2024-09-19 11:45:46 +0300
commitd4cdc46ca16a5c78b36c5b9b6ad8cac09d6130a0 (patch)
treeb0698dfd0b021acee2959fa1eea3e2328c080b7d /drivers/net/wireless/intel/iwlegacy/common.c
parent34b69548108480ebb36cb6a067974a88ec745897 (diff)
wifi: iwlegacy: Fix "field-spanning write" warning in il_enqueue_hcmd()
iwlegacy uses command buffers with a payload size of 320 bytes (default) or 4092 bytes (huge). The struct il_device_cmd type describes the default buffers and there is no separate type describing the huge buffers. The il_enqueue_hcmd() function works with both default and huge buffers, and has a memcpy() to the buffer payload. The size of this copy may exceed 320 bytes when using a huge buffer, which now results in a run-time warning: memcpy: detected field-spanning write (size 1014) of single field "&out_cmd->cmd.payload" at drivers/net/wireless/intel/iwlegacy/common.c:3170 (size 320) To fix this: - Define a new struct type for huge buffers, with a correctly sized payload field - When using a huge buffer in il_enqueue_hcmd(), cast the command buffer pointer to that type when looking up the payload field Reported-by: Martin-Éric Racine <martin-eric.racine@iki.fi> References: https://bugs.debian.org/1062421 References: https://bugzilla.kernel.org/show_bug.cgi?id=219124 Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Fixes: 54d9469bc515 ("fortify: Add run-time WARN for cross-field memcpy()") Tested-by: Martin-Éric Racine <martin-eric.racine@iki.fi> Tested-by: Brandon Nielsen <nielsenb@jetfuse.net> Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://patch.msgid.link/ZuIhQRi/791vlUhE@decadent.org.uk
Diffstat (limited to 'drivers/net/wireless/intel/iwlegacy/common.c')
-rw-r--r--drivers/net/wireless/intel/iwlegacy/common.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c
index 9d33a66a49b5..4616293ec0cf 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -3122,6 +3122,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
struct il_cmd_meta *out_meta;
dma_addr_t phys_addr;
unsigned long flags;
+ u8 *out_payload;
u32 idx;
u16 fix_size;
@@ -3157,6 +3158,16 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
out_cmd = txq->cmd[idx];
out_meta = &txq->meta[idx];
+ /* The payload is in the same place in regular and huge
+ * command buffers, but we need to let the compiler know when
+ * we're using a larger payload buffer to avoid "field-
+ * spanning write" warnings at run-time for huge commands.
+ */
+ if (cmd->flags & CMD_SIZE_HUGE)
+ out_payload = ((struct il_device_cmd_huge *)out_cmd)->cmd.payload;
+ else
+ out_payload = out_cmd->cmd.payload;
+
if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
spin_unlock_irqrestore(&il->hcmd_lock, flags);
return -ENOSPC;
@@ -3170,7 +3181,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
out_meta->callback = cmd->callback;
out_cmd->hdr.cmd = cmd->id;
- memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
+ memcpy(out_payload, cmd->data, cmd->len);
/* At this point, the out_cmd now has all of the incoming cmd
* information */