summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Neal <anna@cozybit.com>2008-10-27 17:36:44 -0700
committerDeepak Saxena <dsaxena@laptop.org>2008-10-31 11:43:24 -0700
commit0bdeaaf080b7c0b9aba1b95315538d08111a679d (patch)
treea7e3e420a16bc0ce1537cfa5000dde437f7d9b20
parent779f36de3d480e1056e8af47cda212d2d05ab31e (diff)
downloadlwn-0bdeaaf080b7c0b9aba1b95315538d08111a679d.tar.gz
lwn-0bdeaaf080b7c0b9aba1b95315538d08111a679d.zip
libertas: fix signature/mask alignment bug
When a rule < 4 bytes was set, the mask was applied to the wrong part of the signature. This patch corrects that. Signed-off-by: Anna Neal <anna@cozybit.com>
-rw-r--r--drivers/net/wireless/libertas/ioctl.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/net/wireless/libertas/ioctl.c b/drivers/net/wireless/libertas/ioctl.c
index 908b930079e5..6ef7d711c386 100644
--- a/drivers/net/wireless/libertas/ioctl.c
+++ b/drivers/net/wireless/libertas/ioctl.c
@@ -1088,23 +1088,21 @@ out:
}
/**
- * ascii_to_be32() - Convert an hex ascii string into a be32 integer.
- * @dst: Pointer to destination big endiand 32 bit integer.
+ * ascii_to_u32() - Convert an hex ascii string into a u32 integer.
+ * @dst: Pointer to destination unsigned 32 bit integer.
* @pptr: Input string. On exit points past the last converted character.
*
* Returns the number of converted characters.
**/
-static int ascii_to_be32(__be32 *dst, unsigned char **pptr)
+static int ascii_to_u32(u32 *dst, unsigned char **pptr)
{
- uint32_t value;
unsigned char *start;
int char_count;
start = *pptr;
if (**pptr == '0' && tolower(*(*pptr+1)) == 'x')
start += 2;
- value = simple_strtoul((char *)*pptr, (char **) pptr, 16);
- *dst = cpu_to_be32(value);
+ *dst = simple_strtoul((char *)*pptr, (char **) pptr, 16);
char_count = (*pptr - start);
@@ -1130,6 +1128,7 @@ static int config_set_wol_rule(unsigned char *ptr, struct wol_config *rules)
unsigned short sig_offset;
int sig_len, msk_len;
int n, ret;
+ u32 temp_u32;
ptr = next_param(ptr);
if (!ptr)
@@ -1149,22 +1148,26 @@ static int config_set_wol_rule(unsigned char *ptr, struct wol_config *rules)
return -EINVAL;
rules->rule[n].rule_no = n;
- sig_len = ascii_to_be32(&rules->rule[n].signature, &ptr);
+ sig_len = ascii_to_u32(&temp_u32, &ptr);
if (sig_len <= 0)
return -EINVAL;
+ rules->rule[n].signature = cpu_to_be32(temp_u32 <<
+ 4*(8-sig_len));
/* No signature mask, build a default one */
if (*ptr == '@') {
uint32_t defmask;
- defmask = (0xffffffff >> 4*(8-sig_len));
+ defmask = (0xffffffff << 4*(8-sig_len));
rules->rule[n].sig_mask = cpu_to_be32(defmask);
msk_len = sig_len;
} else if (*ptr == '.') {
ptr++;
- msk_len = ascii_to_be32(&rules->rule[n].sig_mask, &ptr);
+ msk_len = ascii_to_u32(&temp_u32, &ptr);
if (msk_len <= 0)
return -EINVAL;
+ rules->rule[n].sig_mask = cpu_to_be32(temp_u32 <<
+ 4*(8-msk_len));
} else
return -EINVAL;