diff options
author | 2017-08-11 19:53:02 +0000 | |
---|---|---|
committer | 2017-08-11 19:53:02 +0000 | |
commit | b2a698ea6719f662ac4da32c3ddecf2a70ba1bfa (patch) | |
tree | 22f6930257029040f57e778eac3c8e68c738b004 /sys/netinet6 | |
parent | Check whether the first two characters of $HISTFILE are the magic (diff) | |
download | wireguard-openbsd-b2a698ea6719f662ac4da32c3ddecf2a70ba1bfa.tar.xz wireguard-openbsd-b2a698ea6719f662ac4da32c3ddecf2a70ba1bfa.zip |
Validate sockaddr from userland in central functions. This results
in common checks for unix, inet, inet6 instead of partial checks
here and there. Some checks are already done at a higher layer,
but better be paranoid with user input.
OK claudio@ millert@
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6.c | 20 | ||||
-rw-r--r-- | sys/netinet6/in6.h | 3 | ||||
-rw-r--r-- | sys/netinet6/in6_pcb.c | 14 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 24 | ||||
-rw-r--r-- | sys/netinet6/udp6_output.c | 13 |
5 files changed, 34 insertions, 40 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index ce28f466a5c..b83e6df6c66 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.209 2017/08/08 18:15:58 florian Exp $ */ +/* $OpenBSD: in6.c,v 1.210 2017/08/11 19:53:02 bluhm Exp $ */ /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */ /* @@ -164,6 +164,24 @@ in6_mask2len(struct in6_addr *mask, u_char *lim0) } int +in6_nam2sin6(const struct mbuf *nam, struct sockaddr_in6 **sin6) +{ + struct sockaddr *sa = mtod(nam, struct sockaddr *); + + if (nam->m_len < offsetof(struct sockaddr, sa_data)) + return EINVAL; + if (sa->sa_family != AF_INET6) + return EAFNOSUPPORT; + if (sa->sa_len != nam->m_len) + return EINVAL; + if (sa->sa_len != sizeof(struct sockaddr_in6)) + return EINVAL; + *sin6 = satosin6(sa); + + return 0; +} + +int in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp) { int privileged; diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index ac0120e4217..0caae1f586a 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.h,v 1.97 2017/07/13 17:17:27 florian Exp $ */ +/* $OpenBSD: in6.h,v 1.98 2017/08/11 19:53:02 bluhm Exp $ */ /* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */ /* @@ -420,6 +420,7 @@ int in6_addrscope(struct in6_addr *); struct in6_ifaddr *in6_ifawithscope(struct ifnet *, struct in6_addr *, u_int); void in6_get_rand_ifid(struct ifnet *, struct in6_addr *); int in6_mask2len(struct in6_addr *, u_char *); +int in6_nam2sin6(const struct mbuf *, struct sockaddr_in6 **); struct inpcb; diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index ae7eb146bfe..194eabf1b1b 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_pcb.c,v 1.99 2017/08/04 18:16:42 bluhm Exp $ */ +/* $OpenBSD: in6_pcb.c,v 1.100 2017/08/11 19:53:02 bluhm Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -244,16 +244,12 @@ int in6_pcbconnect(struct inpcb *inp, struct mbuf *nam) { struct in6_addr *in6a = NULL; - struct sockaddr_in6 *sin6 = mtod(nam, struct sockaddr_in6 *); - int error = 0; + struct sockaddr_in6 *sin6; + int error; struct sockaddr_in6 tmp; - (void)&in6a; /* XXX fool gcc */ - - if (nam->m_len != sizeof(*sin6)) - return (EINVAL); - if (sin6->sin6_family != AF_INET6) - return (EAFNOSUPPORT); + if ((error = in6_nam2sin6(nam, &sin6))) + return (error); if (sin6->sin6_port == 0) return (EADDRNOTAVAIL); /* reject IPv4 mapped address, we have no support for it */ diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 9f989ef006b..f1c44f77a49 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip6.c,v 1.115 2017/06/26 09:32:32 mpi Exp $ */ +/* $OpenBSD: raw_ip6.c,v 1.116 2017/08/11 19:53:02 bluhm Exp $ */ /* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */ /* @@ -609,17 +609,10 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, case PRU_BIND: { - struct sockaddr_in6 *addr = mtod(nam, struct sockaddr_in6 *); + struct sockaddr_in6 *addr; - if (nam->m_len != sizeof(*addr)) { - error = EINVAL; - break; - } - if (addr->sin6_family != AF_INET6) { - error = EADDRNOTAVAIL; + if ((error = in6_nam2sin6(nam, &addr))) break; - } - /* * Make sure to not enter in_pcblookup_local(), local ports * are non-sensical for raw sockets. @@ -635,18 +628,11 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, case PRU_CONNECT: { - struct sockaddr_in6 *addr = mtod(nam, struct sockaddr_in6 *); + struct sockaddr_in6 *addr; struct in6_addr *in6a = NULL; - if (nam->m_len != sizeof(*addr)) { - error = EINVAL; - break; - } - if (addr->sin6_family != AF_INET6) { - error = EAFNOSUPPORT; + if ((error = in6_nam2sin6(nam, &addr))) break; - } - /* Source address selection. XXX: need pcblookup? */ error = in6_pcbselsrc(&in6a, addr, in6p, in6p->inp_outputopts6); if (error) diff --git a/sys/netinet6/udp6_output.c b/sys/netinet6/udp6_output.c index 34f8a1c0318..ecece8ae82d 100644 --- a/sys/netinet6/udp6_output.c +++ b/sys/netinet6/udp6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp6_output.c,v 1.54 2017/05/13 17:44:38 bluhm Exp $ */ +/* $OpenBSD: udp6_output.c,v 1.55 2017/08/11 19:53:02 bluhm Exp $ */ /* $KAME: udp6_output.c,v 1.21 2001/02/07 11:51:54 itojun Exp $ */ /* @@ -117,16 +117,10 @@ udp6_output(struct inpcb *in6p, struct mbuf *m, struct mbuf *addr6, optp = in6p->inp_outputopts6; if (addr6) { - struct sockaddr_in6 *sin6 = mtod(addr6, struct sockaddr_in6 *); + struct sockaddr_in6 *sin6; - if (addr6->m_len != sizeof(*sin6)) { - error = EINVAL; - goto release; - } - if (sin6->sin6_family != AF_INET6) { - error = EAFNOSUPPORT; + if ((error = in6_nam2sin6(addr6, &sin6))) goto release; - } if (sin6->sin6_port == 0) { error = EADDRNOTAVAIL; goto release; @@ -135,7 +129,6 @@ udp6_output(struct inpcb *in6p, struct mbuf *m, struct mbuf *addr6, error = EADDRNOTAVAIL; goto release; } - if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_faddr6)) { error = EISCONN; goto release; |