| From e33761e6f23881de9f3ee77cc2204ab2e26f3d9a Mon Sep 17 00:00:00 2001 |
| From: Michael Buesch <mb@bu3sch.de> |
| Date: Mon, 23 Nov 2009 20:58:06 +0100 |
| Subject: ssb: Fix range check in sprom write |
| |
| From: Michael Buesch <mb@bu3sch.de> |
| |
| commit e33761e6f23881de9f3ee77cc2204ab2e26f3d9a upstream. |
| |
| The range check in the sprom image parser hex2sprom() is broken. |
| One sprom word is 4 hex characters. |
| This fixes the check and also adds much better sanity checks to the code. |
| We better make sure the image is OK by doing some sanity checks to avoid |
| bricking the device by accident. |
| |
| Signed-off-by: Michael Buesch <mb@bu3sch.de> |
| Signed-off-by: John W. Linville <linville@tuxdriver.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/ssb/sprom.c | 20 ++++++++++++++++---- |
| 1 file changed, 16 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/ssb/sprom.c |
| +++ b/drivers/ssb/sprom.c |
| @@ -13,6 +13,8 @@ |
| |
| #include "ssb_private.h" |
| |
| +#include <linux/ctype.h> |
| + |
| |
| static const struct ssb_sprom *fallback_sprom; |
| |
| @@ -33,17 +35,27 @@ static int sprom2hex(const u16 *sprom, c |
| static int hex2sprom(u16 *sprom, const char *dump, size_t len, |
| size_t sprom_size_words) |
| { |
| - char tmp[5] = { 0 }; |
| - int cnt = 0; |
| + char c, tmp[5] = { 0 }; |
| + int err, cnt = 0; |
| unsigned long parsed; |
| |
| - if (len < sprom_size_words * 2) |
| + /* Strip whitespace at the end. */ |
| + while (len) { |
| + c = dump[len - 1]; |
| + if (!isspace(c) && c != '\0') |
| + break; |
| + len--; |
| + } |
| + /* Length must match exactly. */ |
| + if (len != sprom_size_words * 4) |
| return -EINVAL; |
| |
| while (cnt < sprom_size_words) { |
| memcpy(tmp, dump, 4); |
| dump += 4; |
| - parsed = simple_strtoul(tmp, NULL, 16); |
| + err = strict_strtoul(tmp, 16, &parsed); |
| + if (err) |
| + return err; |
| sprom[cnt++] = swab16((u16)parsed); |
| } |
| |