Commit 7e8750d0 authored by Dan Carpenter's avatar Dan Carpenter Committed by Greg Kroah-Hartman

media: wl128x: prevent two potential buffer overflows

[ Upstream commit 9c2ccc32 ]

Smatch marks skb->data as untrusted so it warns that "evt_hdr->dlen"
can copy up to 255 bytes and we only have room for two bytes.  Even
if this comes from the firmware and we trust it, the new policy
generally is just to fix it as kernel hardenning.

I can't test this code so I tried to be very conservative.  I considered
not allowing "evt_hdr->dlen == 1" because it doesn't initialize the
whole variable but in the end I decided to allow it and manually
initialized "asic_id" and "asic_ver" to zero.

Fixes: e8454ff7 ("[media] drivers:media:radio: wl128x: FM Driver Common sources")
Signed-off-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent ff560d4b
...@@ -489,7 +489,8 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, ...@@ -489,7 +489,8 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload,
return -EIO; return -EIO;
} }
/* Send response data to caller */ /* Send response data to caller */
if (response != NULL && response_len != NULL && evt_hdr->dlen) { if (response != NULL && response_len != NULL && evt_hdr->dlen &&
evt_hdr->dlen <= payload_len) {
/* Skip header info and copy only response data */ /* Skip header info and copy only response data */
skb_pull(skb, sizeof(struct fm_event_msg_hdr)); skb_pull(skb, sizeof(struct fm_event_msg_hdr));
memcpy(response, skb->data, evt_hdr->dlen); memcpy(response, skb->data, evt_hdr->dlen);
...@@ -583,6 +584,8 @@ static void fm_irq_handle_flag_getcmd_resp(struct fmdev *fmdev) ...@@ -583,6 +584,8 @@ static void fm_irq_handle_flag_getcmd_resp(struct fmdev *fmdev)
return; return;
fm_evt_hdr = (void *)skb->data; fm_evt_hdr = (void *)skb->data;
if (fm_evt_hdr->dlen > sizeof(fmdev->irq_info.flag))
return;
/* Skip header info and copy only response data */ /* Skip header info and copy only response data */
skb_pull(skb, sizeof(struct fm_event_msg_hdr)); skb_pull(skb, sizeof(struct fm_event_msg_hdr));
...@@ -1308,7 +1311,7 @@ static int load_default_rx_configuration(struct fmdev *fmdev) ...@@ -1308,7 +1311,7 @@ static int load_default_rx_configuration(struct fmdev *fmdev)
static int fm_power_up(struct fmdev *fmdev, u8 mode) static int fm_power_up(struct fmdev *fmdev, u8 mode)
{ {
u16 payload; u16 payload;
__be16 asic_id, asic_ver; __be16 asic_id = 0, asic_ver = 0;
int resp_len, ret; int resp_len, ret;
u8 fw_name[50]; u8 fw_name[50];
......
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