On Mon, May 08, 2017 at 05:09:01PM +0200, Alexander Bluhm wrote: > Checking for IPv4 mapped addresses is a bit inconsistent in the > output path.
Here comes the remaining part: - Do not check for mapped addresses in tcp_usrreq(PRU_CONNECT), this is done in in6_pcbconnect(). - Do not check for locally bound mapped addresses in in6_pcbconnect(), this is done during bind(2) in in6_pcbaddrisavail(). - Check for mapped addesses in rip6_output() like it is done in udp6_output(). - Move the EAFNOSUPPORT error from rip6_usrreq() to rip6_output() like it is done for UDP. - Return EADDRNOTAVAIL if UDP sendto(2) is used with a mapped address. ok? bluhm Index: netinet/tcp_usrreq.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_usrreq.c,v retrieving revision 1.148 diff -u -p -r1.148 tcp_usrreq.c --- netinet/tcp_usrreq.c 12 May 2017 20:34:29 -0000 1.148 +++ netinet/tcp_usrreq.c 12 May 2017 20:37:33 -0000 @@ -242,8 +242,7 @@ tcp_usrreq(struct socket *so, int req, s &mtod(nam, struct sockaddr_in6 *)->sin6_addr; if (IN6_IS_ADDR_UNSPECIFIED(addr6) || - IN6_IS_ADDR_MULTICAST(addr6) || - IN6_IS_ADDR_V4MAPPED(addr6)) { + IN6_IS_ADDR_MULTICAST(addr6)) { error = EINVAL; break; } Index: netinet6/in6_pcb.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6_pcb.c,v retrieving revision 1.97 diff -u -p -r1.97 in6_pcb.c --- netinet6/in6_pcb.c 7 Mar 2017 16:59:40 -0000 1.97 +++ netinet6/in6_pcb.c 12 May 2017 20:36:12 -0000 @@ -256,14 +256,9 @@ in6_pcbconnect(struct inpcb *inp, struct return (EAFNOSUPPORT); if (sin6->sin6_port == 0) return (EADDRNOTAVAIL); - /* reject IPv4 mapped address, we have no support for it */ if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) - return EADDRNOTAVAIL; - - /* sanity check for mapped address case */ - if (IN6_IS_ADDR_V4MAPPED(&inp->inp_laddr6)) - return EINVAL; + return (EADDRNOTAVAIL); /* protect *sin6 from overwrites */ tmp = *sin6; Index: netinet6/raw_ip6.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/raw_ip6.c,v retrieving revision 1.113 diff -u -p -r1.113 raw_ip6.c --- netinet6/raw_ip6.c 8 May 2017 08:46:39 -0000 1.113 +++ netinet6/raw_ip6.c 12 May 2017 20:37:22 -0000 @@ -343,7 +343,6 @@ rip6_output(struct mbuf *m, struct socke priv = 0; if ((so->so_state & SS_PRIV) != 0) priv = 1; - dst = &satosin6(dstaddr)->sin6_addr; if (control) { if ((error = ip6_setpktopts(control, &opt, in6p->inp_outputopts6, @@ -353,6 +352,16 @@ rip6_output(struct mbuf *m, struct socke } else optp = in6p->inp_outputopts6; + if (dstaddr->sa_family != AF_INET6) { + error = EAFNOSUPPORT; + goto bad; + } + dst = &satosin6(dstaddr)->sin6_addr; + if (IN6_IS_ADDR_V4MAPPED(dst)) { + error = EADDRNOTAVAIL; + goto bad; + } + /* * For an ICMPv6 packet, we should know its type and code * to update statistics. @@ -691,11 +700,6 @@ rip6_usrreq(struct socket *so, int req, tmp = *mtod(nam, struct sockaddr_in6 *); dst = &tmp; - - if (dst->sin6_family != AF_INET6) { - error = EAFNOSUPPORT; - break; - } } error = rip6_output(m, so, sin6tosa(dst), control); m = NULL; Index: netinet6/udp6_output.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/udp6_output.c,v retrieving revision 1.53 diff -u -p -r1.53 udp6_output.c --- netinet6/udp6_output.c 19 Dec 2016 15:47:19 -0000 1.53 +++ netinet6/udp6_output.c 12 May 2017 20:36:12 -0000 @@ -132,7 +132,7 @@ udp6_output(struct inpcb *in6p, struct m goto release; } if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { - error = EINVAL; + error = EADDRNOTAVAIL; goto release; }