summaryrefslogtreecommitdiff
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2019-11-06 14:51:23 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2019-11-06 14:51:23 +0000
commit4fcc9f259fd9b4b6e8623b59b08b24cb87c787a2 (patch)
tree2333bd3cbe790515b2bbfca654aa698e7c349265 /sys/net/rtsock.c
parente9ad16b1b7a1b3b06fa1368c23d2cf5e7ac39882 (diff)
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
Diffstat (limited to 'sys/net/rtsock.c')
-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)) {