aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJoe Perches <joe@perches.com>2009-09-18 09:04:06 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-22 17:00:05 -0400
commiteb78cd26b9b519d94e20ce9c0697e5056046669d (patch)
tree7957cf4d3d61d5de3152642c0ded0ce230bb2ad1 /lib
parent95acf7d7ed95fdb9bfd5b7a71752701a0e382bd9 (diff)
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>
Diffstat (limited to 'lib')
-rw-r--r--lib/vsprintf.c25
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)
671 return p; 671 return p;
672} 672}
673 673
674static char *ip6_compressed_string(char *p, const struct in6_addr *addr) 674static char *ip6_compressed_string(char *p, const char *addr)
675{ 675{
676 int i; 676 int i;
677 int j; 677 int j;
@@ -683,7 +683,12 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
683 u8 hi; 683 u8 hi;
684 u8 lo; 684 u8 lo;
685 bool needcolon = false; 685 bool needcolon = false;
686 bool useIPv4 = ipv6_addr_v4mapped(addr) || ipv6_addr_is_isatap(addr); 686 bool useIPv4;
687 struct in6_addr in6;
688
689 memcpy(&in6, addr, sizeof(struct in6_addr));
690
691 useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
687 692
688 memset(zerolength, 0, sizeof(zerolength)); 693 memset(zerolength, 0, sizeof(zerolength));
689 694
@@ -695,7 +700,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
695 /* find position of longest 0 run */ 700 /* find position of longest 0 run */
696 for (i = 0; i < range; i++) { 701 for (i = 0; i < range; i++) {
697 for (j = i; j < range; j++) { 702 for (j = i; j < range; j++) {
698 if (addr->s6_addr16[j] != 0) 703 if (in6.s6_addr16[j] != 0)
699 break; 704 break;
700 zerolength[i]++; 705 zerolength[i]++;
701 } 706 }
@@ -722,7 +727,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
722 needcolon = false; 727 needcolon = false;
723 } 728 }
724 /* hex u16 without leading 0s */ 729 /* hex u16 without leading 0s */
725 word = ntohs(addr->s6_addr16[i]); 730 word = ntohs(in6.s6_addr16[i]);
726 hi = word >> 8; 731 hi = word >> 8;
727 lo = word & 0xff; 732 lo = word & 0xff;
728 if (hi) { 733 if (hi) {
@@ -741,19 +746,19 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
741 if (useIPv4) { 746 if (useIPv4) {
742 if (needcolon) 747 if (needcolon)
743 *p++ = ':'; 748 *p++ = ':';
744 p = ip4_string(p, &addr->s6_addr[12], false); 749 p = ip4_string(p, &in6.s6_addr[12], false);
745 } 750 }
746 751
747 *p = '\0'; 752 *p = '\0';
748 return p; 753 return p;
749} 754}
750 755
751static char *ip6_string(char *p, const struct in6_addr *addr, const char *fmt) 756static char *ip6_string(char *p, const char *addr, const char *fmt)
752{ 757{
753 int i; 758 int i;
754 for (i = 0; i < 8; i++) { 759 for (i = 0; i < 8; i++) {
755 p = pack_hex_byte(p, addr->s6_addr[2 * i]); 760 p = pack_hex_byte(p, *addr++);
756 p = pack_hex_byte(p, addr->s6_addr[2 * i + 1]); 761 p = pack_hex_byte(p, *addr++);
757 if (fmt[0] == 'I' && i != 7) 762 if (fmt[0] == 'I' && i != 7)
758 *p++ = ':'; 763 *p++ = ':';
759 } 764 }
@@ -768,9 +773,9 @@ static char *ip6_addr_string(char *buf, char *end, const u8 *addr,
768 char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")]; 773 char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
769 774
770 if (fmt[0] == 'I' && fmt[2] == 'c') 775 if (fmt[0] == 'I' && fmt[2] == 'c')
771 ip6_compressed_string(ip6_addr, (const struct in6_addr *)addr); 776 ip6_compressed_string(ip6_addr, addr);
772 else 777 else
773 ip6_string(ip6_addr, (const struct in6_addr *)addr, fmt); 778 ip6_string(ip6_addr, addr, fmt);
774 779
775 return string(buf, end, ip6_addr, spec); 780 return string(buf, end, ip6_addr, spec);
776} 781}