diff options
| author | 2020-05-20 18:27:16 +0000 | |
|---|---|---|
| committer | 2020-05-20 18:27:16 +0000 | |
| commit | cec60a45d9fdbe9601abd8cb4776999d7fbc8a2f (patch) | |
| tree | 68fdb9519c0d6cd978adabf73ecfe60c86501d9f | |
| parent | kernel.h: remove global declaration for naptime (diff) | |
| download | wireguard-openbsd-cec60a45d9fdbe9601abd8cb4776999d7fbc8a2f.tar.xz wireguard-openbsd-cec60a45d9fdbe9601abd8cb4776999d7fbc8a2f.zip | |
Replace fixed 128-byte fields for search domains, static routes and
domain name servers with variable sized uint8_t chunks.
Allows larger lists of search domains and static routes while making
common situations use much less memory.
Original report of breaching the 128-byte limit for static routes from
James Cook via misc@.
Testing of various versions by Andreas Kusalananda.
| -rw-r--r-- | sbin/dhclient/dhclient.c | 29 | ||||
| -rw-r--r-- | sbin/dhclient/kroute.c | 38 | ||||
| -rw-r--r-- | sbin/dhclient/privsep.c | 5 | ||||
| -rw-r--r-- | sbin/dhclient/privsep.h | 7 |
4 files changed, 47 insertions, 32 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index 40e8d566db1..a46179a8e9f 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.671 2020/05/15 19:40:44 krw Exp $ */ +/* $OpenBSD: dhclient.c,v 1.672 2020/05/20 18:27:16 krw Exp $ */ /* * Copyright 2004 Henning Brauer <henning@openbsd.org> @@ -1981,7 +1981,7 @@ lease_as_proposal(struct client_lease *lease) struct option_data fake; struct option_data *opt; struct proposal *proposal; - uint8_t *routes, *search, *dns; + uint8_t *dns, *p, *routes, *search; unsigned int routes_len = 0, search_len = 0, dns_len = 0; uint16_t mtu; @@ -2022,7 +2022,8 @@ lease_as_proposal(struct client_lease *lease) } /* Allocate proposal. */ - proposal = calloc(1, sizeof(*proposal)); + proposal = calloc(1, sizeof(*proposal) + routes_len + search_len + + dns_len); if (proposal == NULL) fatal("proposal"); @@ -2039,18 +2040,16 @@ lease_as_proposal(struct client_lease *lease) if (opt->len == sizeof(proposal->netmask)) memcpy(&proposal->netmask, opt->data, opt->len); - if (routes_len > 0 && routes_len < sizeof(proposal->rtstatic)) { - memcpy(proposal->rtstatic, routes, routes_len); - proposal->rtstatic_len = routes_len; - } - if (search_len > 0 && search_len < sizeof(proposal->rtsearch)) { - memcpy(proposal->rtsearch, search, search_len); - proposal->rtsearch_len = search_len; - } - if (dns_len > 0 && dns_len <= sizeof(proposal->rtdns)) { - memcpy(proposal->rtdns, dns, dns_len); - proposal->rtdns_len = dns_len; - } + /* Append variable length uint8_t data. */ + p = (uint8_t *)proposal + sizeof(struct proposal); + memcpy(p, routes, routes_len); + p += routes_len; + proposal->rtstatic_len = routes_len; + memcpy(p, search, search_len); + p += search_len; + proposal->rtsearch_len = search_len; + memcpy(p, dns, dns_len); + proposal->rtdns_len = dns_len; return proposal; } diff --git a/sbin/dhclient/kroute.c b/sbin/dhclient/kroute.c index a43dddeba9e..a97edfaf3cc 100644 --- a/sbin/dhclient/kroute.c +++ b/sbin/dhclient/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.176 2020/05/19 17:59:47 krw Exp $ */ +/* $OpenBSD: kroute.c,v 1.177 2020/05/20 18:27:16 krw Exp $ */ /* * Copyright 2012 Kenneth R Westerback <krw@openbsd.org> @@ -884,20 +884,31 @@ propose(struct proposal *proposal) int rslt; rslt = imsg_compose(unpriv_ibuf, IMSG_PROPOSE, 0, 0, -1, proposal, - sizeof(*proposal)); + sizeof(*proposal) + proposal->rtstatic_len + + proposal->rtsearch_len + proposal->rtdns_len); if (rslt == -1) log_warn("%s: imsg_compose(IMSG_PROPOSE)", log_procname); } void priv_propose(char *name, int ioctlfd, struct proposal *proposal, - char **resolv_conf, int routefd, int rdomain, int index) + size_t sz, char **resolv_conf, int routefd, int rdomain, int index) { struct unwind_info unwind_info; struct ifreq ifr; + uint8_t *dns, *domains, *routes; char *search = NULL; int rslt; + if (sz != proposal->rtstatic_len + proposal->rtsearch_len + proposal->rtdns_len) { + log_warnx("%s: bad IMSG_PROPOSE data", log_procname); + return; + } + + routes = (uint8_t *)proposal + sizeof(struct proposal); + domains = routes + proposal->rtstatic_len; + dns = domains + proposal->rtsearch_len; + memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); if (ioctl(ioctlfd, SIOCGIFXFLAGS, (caddr_t)&ifr) < 0) @@ -905,15 +916,22 @@ priv_propose(char *name, int ioctlfd, struct proposal *proposal, if ((ifr.ifr_flags & IFXF_AUTOCONF4) == 0) return; - memset(unwind_info.ns, 0, sizeof(unwind_info.ns)); - if (proposal->rtdns_len > sizeof(unwind_info.ns)) - proposal->rtdns_len = sizeof(unwind_info.ns); - memcpy(unwind_info.ns, proposal->rtdns, proposal->rtdns_len); - unwind_info.count = proposal->rtdns_len / sizeof(in_addr_t); + memset(&unwind_info, 0, sizeof(unwind_info)); + if (proposal->rtdns_len >= sizeof(in_addr_t)) { + if (proposal->rtdns_len > sizeof(unwind_info.ns)) { + memcpy(unwind_info.ns, dns, sizeof(unwind_info.ns)); + unwind_info.count = sizeof(unwind_info.ns) / + sizeof(in_addr_t); + } else { + memcpy(unwind_info.ns, dns, proposal->rtdns_len); + unwind_info.count = proposal->rtdns_len / + sizeof(in_addr_t); + } + } if (proposal->rtsearch_len > 0) { rslt = asprintf(&search, "search %.*s\n", - proposal->rtsearch_len, proposal->rtsearch); + proposal->rtsearch_len, domains); if (rslt == -1) search = NULL; } @@ -933,7 +951,7 @@ priv_propose(char *name, int ioctlfd, struct proposal *proposal, set_address(name, ioctlfd, proposal->ifa, proposal->netmask); set_routes(name, index, rdomain, routefd, proposal->ifa, - proposal->netmask, proposal->rtstatic, proposal->rtstatic_len); + proposal->netmask, routes, proposal->rtstatic_len); } /* diff --git a/sbin/dhclient/privsep.c b/sbin/dhclient/privsep.c index e57268c2352..a17d9046812 100644 --- a/sbin/dhclient/privsep.c +++ b/sbin/dhclient/privsep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: privsep.c,v 1.77 2020/05/19 17:59:47 krw Exp $ */ +/* $OpenBSD: privsep.c,v 1.78 2020/05/20 18:27:16 krw Exp $ */ /* * Copyright (c) 2004 Henning Brauer <henning@openbsd.org> @@ -75,12 +75,13 @@ dispatch_imsg(char *name, int rdomain, int ioctlfd, int routefd, break; case IMSG_PROPOSE: - if (imsg.hdr.len != IMSG_HEADER_SIZE + + if (imsg.hdr.len < IMSG_HEADER_SIZE + sizeof(struct proposal)) log_warnx("%s: bad IMSG_PROPOSE", log_procname); else { priv_propose(name, ioctlfd, imsg.data, + imsg.hdr.len - IMSG_HEADER_SIZE - sizeof(struct proposal), &resolv_conf, routefd, rdomain, index); lastidx = 0; /* Next IMSG_WRITE_RESOLV_CONF */ } diff --git a/sbin/dhclient/privsep.h b/sbin/dhclient/privsep.h index 4bed6e29930..39caf58aab3 100644 --- a/sbin/dhclient/privsep.h +++ b/sbin/dhclient/privsep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: privsep.h,v 1.64 2020/05/19 17:59:47 krw Exp $ */ +/* $OpenBSD: privsep.h,v 1.65 2020/05/20 18:27:16 krw Exp $ */ /* * Copyright (c) 2004 Henning Brauer <henning@openbsd.org> @@ -27,9 +27,6 @@ enum imsg_code { #define RTLEN 128 struct proposal { - uint8_t rtstatic[RTLEN]; - uint8_t rtsearch[RTLEN]; - uint8_t rtdns[RTLEN]; struct in_addr ifa; struct in_addr netmask; unsigned int rtstatic_len; @@ -46,7 +43,7 @@ struct unwind_info { void dispatch_imsg(char *, int, int, int, struct imsgbuf *); void priv_write_resolv_conf(int, int, int, char *, int *); -void priv_propose(char *, int, struct proposal *, char **, int, int, int); +void priv_propose(char *, int, struct proposal *, size_t, char **, int, int, int); void priv_revoke_proposal(char *, int, struct proposal *, char **); |
