diff options
author | Joe Perches <joe@perches.com> | 2009-09-18 13:04:06 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-22 14:00:05 -0700 |
commit | eb78cd26b9b519d94e20ce9c0697e5056046669d (patch) | |
tree | 7957cf4d3d61d5de3152642c0ded0ce230bb2ad1 | |
parent | 95acf7d7ed95fdb9bfd5b7a71752701a0e382bd9 (diff) | |
download | linux-eb78cd26b9b519d94e20ce9c0697e5056046669d.tar.gz linux-eb78cd26b9b519d94e20ce9c0697e5056046669d.tar.bz2 linux-eb78cd26b9b519d94e20ce9c0697e5056046669d.zip |
lib/vsprintf.c: Avoid possible unaligned accesses in %pI6c
Jens Rosenboom noticed that a possibly unaligned const char*
is cast to a const struct in6_addr *.
Avoid this at the cost of a struct in6_addr copy on the stack.
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | lib/vsprintf.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index cb8a112030bb..a1941f8d205f 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -671,7 +671,7 @@ static char *ip4_string(char *p, const u8 *addr, bool leading_zeros) return p; } -static char *ip6_compressed_string(char *p, const struct in6_addr *addr) +static char *ip6_compressed_string(char *p, const char *addr) { int i; int j; @@ -683,7 +683,12 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr) u8 hi; u8 lo; bool needcolon = false; - bool useIPv4 = ipv6_addr_v4mapped(addr) || ipv6_addr_is_isatap(addr); + bool useIPv4; + struct in6_addr in6; + + memcpy(&in6, addr, sizeof(struct in6_addr)); + + useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6); memset(zerolength, 0, sizeof(zerolength)); @@ -695,7 +700,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr) /* find position of longest 0 run */ for (i = 0; i < range; i++) { for (j = i; j < range; j++) { - if (addr->s6_addr16[j] != 0) + if (in6.s6_addr16[j] != 0) break; zerolength[i]++; } @@ -722,7 +727,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr) needcolon = false; } /* hex u16 without leading 0s */ - word = ntohs(addr->s6_addr16[i]); + word = ntohs(in6.s6_addr16[i]); hi = word >> 8; lo = word & 0xff; if (hi) { @@ -741,19 +746,19 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr) if (useIPv4) { if (needcolon) *p++ = ':'; - p = ip4_string(p, &addr->s6_addr[12], false); + p = ip4_string(p, &in6.s6_addr[12], false); } *p = '\0'; return p; } -static char *ip6_string(char *p, const struct in6_addr *addr, const char *fmt) +static char *ip6_string(char *p, const char *addr, const char *fmt) { int i; for (i = 0; i < 8; i++) { - p = pack_hex_byte(p, addr->s6_addr[2 * i]); - p = pack_hex_byte(p, addr->s6_addr[2 * i + 1]); + p = pack_hex_byte(p, *addr++); + p = pack_hex_byte(p, *addr++); if (fmt[0] == 'I' && i != 7) *p++ = ':'; } @@ -768,9 +773,9 @@ static char *ip6_addr_string(char *buf, char *end, const u8 *addr, char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")]; if (fmt[0] == 'I' && fmt[2] == 'c') - ip6_compressed_string(ip6_addr, (const struct in6_addr *)addr); + ip6_compressed_string(ip6_addr, addr); else - ip6_string(ip6_addr, (const struct in6_addr *)addr, fmt); + ip6_string(ip6_addr, addr, fmt); return string(buf, end, ip6_addr, spec); } |