summaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
authorDan Carpenter <dan.carpenter@oracle.com>2019-03-26 01:12:07 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-03-29 07:43:48 -0400
commit9c2ccc324b3a6cbc865ab8b3e1a09e93d3c8ade9 (patch)
tree31d6c625fee9e81e91460363d7542b8af91f25ea /drivers/media/radio
parent2e7682ebfc750177a4944eeb56e97a3f05734528 (diff)
downloadlinux-9c2ccc324b3a6cbc865ab8b3e1a09e93d3c8ade9.tar.gz
linux-9c2ccc324b3a6cbc865ab8b3e1a09e93d3c8ade9.tar.bz2
linux-9c2ccc324b3a6cbc865ab8b3e1a09e93d3c8ade9.zip
media: wl128x: prevent two potential buffer overflows
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: e8454ff7b9a4 ("[media] drivers:media:radio: wl128x: FM Driver Common sources") Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/radio')
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
index 1614809f7d35..a1fcb80a2191 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.c
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -489,7 +489,8 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload,
return -EIO;
}
/* 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 */
skb_pull(skb, sizeof(struct fm_event_msg_hdr));
memcpy(response, skb->data, evt_hdr->dlen);
@@ -583,6 +584,8 @@ static void fm_irq_handle_flag_getcmd_resp(struct fmdev *fmdev)
return;
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 */
skb_pull(skb, sizeof(struct fm_event_msg_hdr));
@@ -1309,7 +1312,7 @@ static int load_default_rx_configuration(struct fmdev *fmdev)
static int fm_power_up(struct fmdev *fmdev, u8 mode)
{
u16 payload;
- __be16 asic_id, asic_ver;
+ __be16 asic_id = 0, asic_ver = 0;
int resp_len, ret;
u8 fw_name[50];