]>
Commit | Line | Data |
---|---|---|
1143c684 SL |
1 | From 27595e80a573667ee8954defa3be9ee701eee729 Mon Sep 17 00:00:00 2001 |
2 | From: Dan Carpenter <dan.carpenter@oracle.com> | |
3 | Date: Tue, 26 Mar 2019 01:12:07 -0400 | |
4 | Subject: media: wl128x: prevent two potential buffer overflows | |
5 | ||
6 | [ Upstream commit 9c2ccc324b3a6cbc865ab8b3e1a09e93d3c8ade9 ] | |
7 | ||
8 | Smatch marks skb->data as untrusted so it warns that "evt_hdr->dlen" | |
9 | can copy up to 255 bytes and we only have room for two bytes. Even | |
10 | if this comes from the firmware and we trust it, the new policy | |
11 | generally is just to fix it as kernel hardenning. | |
12 | ||
13 | I can't test this code so I tried to be very conservative. I considered | |
14 | not allowing "evt_hdr->dlen == 1" because it doesn't initialize the | |
15 | whole variable but in the end I decided to allow it and manually | |
16 | initialized "asic_id" and "asic_ver" to zero. | |
17 | ||
18 | Fixes: e8454ff7b9a4 ("[media] drivers:media:radio: wl128x: FM Driver Common sources") | |
19 | ||
20 | Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> | |
21 | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | |
22 | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | |
23 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
24 | --- | |
25 | drivers/media/radio/wl128x/fmdrv_common.c | 7 +++++-- | |
26 | 1 file changed, 5 insertions(+), 2 deletions(-) | |
27 | ||
28 | diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c | |
29 | index ebc73b0342496..51639a3f7abe4 100644 | |
30 | --- a/drivers/media/radio/wl128x/fmdrv_common.c | |
31 | +++ b/drivers/media/radio/wl128x/fmdrv_common.c | |
32 | @@ -494,7 +494,8 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, | |
33 | return -EIO; | |
34 | } | |
35 | /* Send response data to caller */ | |
36 | - if (response != NULL && response_len != NULL && evt_hdr->dlen) { | |
37 | + if (response != NULL && response_len != NULL && evt_hdr->dlen && | |
38 | + evt_hdr->dlen <= payload_len) { | |
39 | /* Skip header info and copy only response data */ | |
40 | skb_pull(skb, sizeof(struct fm_event_msg_hdr)); | |
41 | memcpy(response, skb->data, evt_hdr->dlen); | |
42 | @@ -590,6 +591,8 @@ static void fm_irq_handle_flag_getcmd_resp(struct fmdev *fmdev) | |
43 | return; | |
44 | ||
45 | fm_evt_hdr = (void *)skb->data; | |
46 | + if (fm_evt_hdr->dlen > sizeof(fmdev->irq_info.flag)) | |
47 | + return; | |
48 | ||
49 | /* Skip header info and copy only response data */ | |
50 | skb_pull(skb, sizeof(struct fm_event_msg_hdr)); | |
51 | @@ -1315,7 +1318,7 @@ static int load_default_rx_configuration(struct fmdev *fmdev) | |
52 | static int fm_power_up(struct fmdev *fmdev, u8 mode) | |
53 | { | |
54 | u16 payload; | |
55 | - __be16 asic_id, asic_ver; | |
56 | + __be16 asic_id = 0, asic_ver = 0; | |
57 | int resp_len, ret; | |
58 | u8 fw_name[50]; | |
59 | ||
60 | -- | |
61 | 2.20.1 | |
62 |