summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkrw <krw@openbsd.org>2020-05-20 18:27:16 +0000
committerkrw <krw@openbsd.org>2020-05-20 18:27:16 +0000
commitcec60a45d9fdbe9601abd8cb4776999d7fbc8a2f (patch)
tree68fdb9519c0d6cd978adabf73ecfe60c86501d9f
parentkernel.h: remove global declaration for naptime (diff)
downloadwireguard-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.c29
-rw-r--r--sbin/dhclient/kroute.c38
-rw-r--r--sbin/dhclient/privsep.c5
-rw-r--r--sbin/dhclient/privsep.h7
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 **);