diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2019-11-06 14:51:23 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2019-11-06 14:51:23 +0000 |
commit | 4fcc9f259fd9b4b6e8623b59b08b24cb87c787a2 (patch) | |
tree | 2333bd3cbe790515b2bbfca654aa698e7c349265 /sys/net/rtsock.c | |
parent | e9ad16b1b7a1b3b06fa1368c23d2cf5e7ac39882 (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.c | 36 |
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)) { |