aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAmitkumar Karwar <akarwar@marvell.com>2013-10-22 18:24:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-11-11 14:38:56 -0500
commitfe1c9a443e0d1e0af790883f091fb1c4f418bc8f (patch)
tree5bb5700952ca24730ebd1f253353290d38a29b0e /drivers/net
parent930fd35c8de88cc1ce934aa655181c4879422a37 (diff)
mwifiex: fix invalid memory access in mwifiex_get_power_level()
With "while (length)" check we may end up in accessing invalid memory in last iteration. This patch makes sure that tlv length is not less than the length of structure mwifiex_power_group when min/max power is calculated. Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index bdf50fd5ef6b..5edea4dd05a8 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -341,12 +341,16 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
341 pg = (struct mwifiex_power_group *) 341 pg = (struct mwifiex_power_group *)
342 ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group)); 342 ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group));
343 length = le16_to_cpu(pg_tlv_hdr->length); 343 length = le16_to_cpu(pg_tlv_hdr->length);
344 if (length > 0) { 344
345 max_power = pg->power_max; 345 /* At least one structure required to update power */
346 min_power = pg->power_min; 346 if (length < sizeof(struct mwifiex_power_group))
347 length -= sizeof(struct mwifiex_power_group); 347 return 0;
348 } 348
349 while (length) { 349 max_power = pg->power_max;
350 min_power = pg->power_min;
351 length -= sizeof(struct mwifiex_power_group);
352
353 while (length >= sizeof(struct mwifiex_power_group)) {
350 pg++; 354 pg++;
351 if (max_power < pg->power_max) 355 if (max_power < pg->power_max)
352 max_power = pg->power_max; 356 max_power = pg->power_max;
@@ -356,10 +360,8 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
356 360
357 length -= sizeof(struct mwifiex_power_group); 361 length -= sizeof(struct mwifiex_power_group);
358 } 362 }
359 if (le16_to_cpu(pg_tlv_hdr->length) > 0) { 363 priv->min_tx_power_level = (u8) min_power;
360 priv->min_tx_power_level = (u8) min_power; 364 priv->max_tx_power_level = (u8) max_power;
361 priv->max_tx_power_level = (u8) max_power;
362 }
363 365
364 return 0; 366 return 0;
365} 367}