2002/05/16      yoshfuji
       * kernel/linux2{2,4}/net/ipv6/icmp.c, src/iputils/ping6.c:
       [SECURITY] fixed buffer overrun while calculating node group address.

Index: net/ipv6/icmp.c
===================================================================
RCS file: /cvsroot/usagi/usagi/kernel/linux24/net/ipv6/icmp.c,v
retrieving revision 1.149
retrieving revision 1.149.6.2
diff -u -r1.149 -r1.149.6.2
--- net/ipv6/icmp.c     2001/09/24 07:38:47     1.149
+++ net/ipv6/icmp.c     2002/05/16 02:53:33     1.149.6.2
@@ -1,4 +1,4 @@
-/* $USAGI: icmp.c,v 1.149 2001/09/24 07:38:47 yoshfuji Exp $ */
+/* $USAGI: icmp.c,v 1.149.6.2 2002/05/16 02:53:33 yoshfuji Exp $ */

/*
 *     Internet Control Message Protocol (ICMPv6)
@@ -527,12 +527,12 @@
               icmpv6_ni_qtype_table[qtype].name : "unknown");
}

-static size_t str2lower(char *dst, const char *src)
+static size_t str2lower(char *dst, const char *src, size_t len)
{
       const char *p;
       char *q;
       size_t i;
-       for (p = src, q = dst, i = 0; *p; p++, i++)
+       for (p = src, q = dst, i = 0; *p && i + 1 < len; p++, i++)
               *q++ = isupper(*p) ? tolower(*p) : *p;
       *q = '\0';
       return i;
@@ -546,7 +546,7 @@
       char hbuf[NI_MAX_SYSNAME_LEN];
       struct in6_addr in6;
       int len;
-       (void)str2lower(&hbuf[1], name);
+       (void)str2lower(&hbuf[1], name, sizeof(hbuf)-1);
       p = strchr(&hbuf[1], '.');
       len = p ? (p - &hbuf[1]) : strlen(&hbuf[1]);
       if (len >= 0x40) {
@@ -726,13 +726,13 @@
               char *cp = (char *)dst;
               int dcnt = 0;
#ifdef CONFIG_IPV6_NODEINFO_USE_UTS_DOMAIN
-               size_t nodelen = str2lower(cp + 1, system_utsname.nodename);
+               size_t nodelen = str2lower(cp + 1, system_utsname.nodename, sizeof(system_utsname.nodename));
               if (strcmp(system_utsname.domainname, __UTS_NODENAME_NONE)) {
                       *(cp + 1 + nodelen) = '.';
-                       (void)str2lower(cp + 1 + nodelen + 1, system_utsname.domainname);
+                       (void)str2lower(cp + 1 + nodelen + 1, system_utsname.domainname, sizeof(system_utsname.domainname));
               }
#else
-               (void)str2lower(cp + 1, system_utsname.nodename);
+               (void)str2lower(cp + 1, system_utsname.nodename, sizeof(system_utsname.nodename));
#endif
               up_read(&uts_sem);
               sysname_known = 1;