diff options
author | Anna Neal <anna@cozybit.com> | 2008-10-27 17:36:44 -0700 |
---|---|---|
committer | Deepak Saxena <dsaxena@laptop.org> | 2008-10-31 11:43:24 -0700 |
commit | 0bdeaaf080b7c0b9aba1b95315538d08111a679d (patch) | |
tree | a7e3e420a16bc0ce1537cfa5000dde437f7d9b20 | |
parent | 779f36de3d480e1056e8af47cda212d2d05ab31e (diff) | |
download | lwn-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.c | 21 |
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; |