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;
}