Skip to content

Commit fe9e4d0

Browse files
ajaykathatjmberg-intel
authored andcommitted
wifi: wilc1000: avoid buffer overflow in WID string configuration
Fix the following copy overflow warning identified by Smatch checker. drivers/net/wireless/microchip/wilc1000/wlan_cfg.c:184 wilc_wlan_parse_response_frame() error: '__memcpy()' 'cfg->s[i]->str' copy overflow (512 vs 65537) This patch introduces size check before accessing the memory buffer. The checks are base on the WID type of received data from the firmware. For WID string configuration, the size limit is determined by individual element size in 'struct wilc_cfg_str_vals' that is maintained in 'len' field of 'struct wilc_cfg_str'. Reported-by: Dan Carpenter <[email protected]> Closes: https://lore.kernel.org/linux-wireless/[email protected] Suggested-by: Dan Carpenter <[email protected]> Signed-off-by: Ajay Singh <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Johannes Berg <[email protected]>
1 parent 62b635d commit fe9e4d0

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

drivers/net/wireless/microchip/wilc1000/wlan_cfg.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ static const struct wilc_cfg_word g_cfg_word[] = {
4141
};
4242

4343
static const struct wilc_cfg_str g_cfg_str[] = {
44-
{WID_FIRMWARE_VERSION, NULL},
45-
{WID_MAC_ADDR, NULL},
46-
{WID_ASSOC_RES_INFO, NULL},
47-
{WID_NIL, NULL}
44+
{WID_FIRMWARE_VERSION, 0, NULL},
45+
{WID_MAC_ADDR, 0, NULL},
46+
{WID_ASSOC_RES_INFO, 0, NULL},
47+
{WID_NIL, 0, NULL}
4848
};
4949

5050
#define WILC_RESP_MSG_TYPE_CONFIG_REPLY 'R'
@@ -147,44 +147,58 @@ static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size)
147147

148148
switch (FIELD_GET(WILC_WID_TYPE, wid)) {
149149
case WID_CHAR:
150+
len = 3;
151+
if (len + 2 > size)
152+
return;
153+
150154
while (cfg->b[i].id != WID_NIL && cfg->b[i].id != wid)
151155
i++;
152156

153157
if (cfg->b[i].id == wid)
154158
cfg->b[i].val = info[4];
155159

156-
len = 3;
157160
break;
158161

159162
case WID_SHORT:
163+
len = 4;
164+
if (len + 2 > size)
165+
return;
166+
160167
while (cfg->hw[i].id != WID_NIL && cfg->hw[i].id != wid)
161168
i++;
162169

163170
if (cfg->hw[i].id == wid)
164171
cfg->hw[i].val = get_unaligned_le16(&info[4]);
165172

166-
len = 4;
167173
break;
168174

169175
case WID_INT:
176+
len = 6;
177+
if (len + 2 > size)
178+
return;
179+
170180
while (cfg->w[i].id != WID_NIL && cfg->w[i].id != wid)
171181
i++;
172182

173183
if (cfg->w[i].id == wid)
174184
cfg->w[i].val = get_unaligned_le32(&info[4]);
175185

176-
len = 6;
177186
break;
178187

179188
case WID_STR:
189+
len = 2 + get_unaligned_le16(&info[2]);
190+
180191
while (cfg->s[i].id != WID_NIL && cfg->s[i].id != wid)
181192
i++;
182193

183-
if (cfg->s[i].id == wid)
194+
if (cfg->s[i].id == wid) {
195+
if (len > cfg->s[i].len || (len + 2 > size))
196+
return;
197+
184198
memcpy(cfg->s[i].str, &info[2],
185-
get_unaligned_le16(&info[2]) + 2);
199+
len);
200+
}
186201

187-
len = 2 + get_unaligned_le16(&info[2]);
188202
break;
189203

190204
default:
@@ -384,12 +398,15 @@ int wilc_wlan_cfg_init(struct wilc *wl)
384398
/* store the string cfg parameters */
385399
wl->cfg.s[i].id = WID_FIRMWARE_VERSION;
386400
wl->cfg.s[i].str = str_vals->firmware_version;
401+
wl->cfg.s[i].len = sizeof(str_vals->firmware_version);
387402
i++;
388403
wl->cfg.s[i].id = WID_MAC_ADDR;
389404
wl->cfg.s[i].str = str_vals->mac_address;
405+
wl->cfg.s[i].len = sizeof(str_vals->mac_address);
390406
i++;
391407
wl->cfg.s[i].id = WID_ASSOC_RES_INFO;
392408
wl->cfg.s[i].str = str_vals->assoc_rsp;
409+
wl->cfg.s[i].len = sizeof(str_vals->assoc_rsp);
393410
i++;
394411
wl->cfg.s[i].id = WID_NIL;
395412
wl->cfg.s[i].str = NULL;

drivers/net/wireless/microchip/wilc1000/wlan_cfg.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@ struct wilc_cfg_word {
2424

2525
struct wilc_cfg_str {
2626
u16 id;
27+
u16 len;
2728
u8 *str;
2829
};
2930

3031
struct wilc_cfg_str_vals {
31-
u8 mac_address[7];
32-
u8 firmware_version[129];
32+
u8 mac_address[8];
33+
u8 firmware_version[130];
3334
u8 assoc_rsp[WILC_MAX_ASSOC_RESP_FRAME_SIZE];
3435
};
3536

0 commit comments

Comments
 (0)