summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorflorian <florian@openbsd.org>2019-11-06 14:51:22 +0000
committerflorian <florian@openbsd.org>2019-11-06 14:51:22 +0000
commit55a58ba7f67016513c99b98723ba9a9cfa9a9477 (patch)
treebf1ee2960ad37e54fc429cb9c138bc777e37883b
parentRename "asr" to "stub" in user visible parts. (diff)
downloadwireguard-openbsd-55a58ba7f67016513c99b98723ba9a9cfa9a9477.tar.xz
wireguard-openbsd-55a58ba7f67016513c99b98723ba9a9cfa9a9477.zip
Fix RTA_DNS checks:
Do not overwrite the address family, we need to know if this is IPv4 or IPv6 to parse the message. Nameservers are IP addresses, not NUL-terminated strings. Check that the length is a multiple of the length of an IP address. OK krw
-rw-r--r--sys/net/rtsock.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 5c1ff50556f..b07ebdc3e60 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.292 2019/09/23 11:00:42 bluhm Exp $ */
+/* $OpenBSD: rtsock.c,v 1.293 2019/11/06 14:51:22 florian Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -1439,9 +1439,21 @@ rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
break;
#endif
case RTAX_DNS:
- sa->sa_family = AF_UNSPEC;
- maxlen = RTDNS_LEN;
- size = sizeof(struct sockaddr_rtdns);
+ /* more validation in rtm_validate_proposal */
+ if (sa->sa_len > sizeof(struct sockaddr_rtdns))
+ return (EINVAL);
+ if (sa->sa_len <= offsetof(struct sockaddr_rtdns,
+ sr_dns))
+ return (EINVAL);
+ switch (sa->sa_family) {
+ case AF_INET:
+#ifdef INET6
+ case AF_INET6:
+#endif
+ break;
+ default:
+ return (EAFNOSUPPORT);
+ }
break;
case RTAX_STATIC:
sa->sa_family = AF_UNSPEC;
@@ -2133,6 +2145,22 @@ rtm_validate_proposal(struct rt_addrinfo *info)
if (rtdns->sr_len <=
offsetof(struct sockaddr_rtdns, sr_dns))
return -1;
+ switch (rtdns->sr_family) {
+ case AF_INET:
+ if ((rtdns->sr_len - offsetof(struct sockaddr_rtdns,
+ sr_dns)) % sizeof(struct in_addr) != 0)
+ return -1;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ if ((rtdns->sr_len - offsetof(struct sockaddr_rtdns,
+ sr_dns)) % sizeof(struct in6_addr) != 0)
+ return -1;
+#endif
+ break;
+ default:
+ return -1;
+ }
}
if (ISSET(info->rti_addrs, RTA_STATIC)) {