summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mack <github@zonque.org>2016-07-15 04:56:11 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-07-14 22:56:11 -0400
commita34349e73348d16d0f41910a38f515f78d18d396 (patch)
tree9816086dbef8e3f0ab58cf3d0fbafaba191bbd3f
parentf749954d924dc126fd3b8a5539b537ddb1a07f71 (diff)
network-ndisc: avoid VLAs (#3725)
Do not allocate objects of dynamic and potentially large size on the stack to avoid both clang compilation errors and unpredictable runtime behavior on exotic platforms. Use the heap for that instead. While at it, refactor the code a bit. Access 's->domain' via NDISC_DNSSL_DOMAIN(), and refrain from allocating 'x' independently, but rather reuse 's' if we're dealing with a new entry to the set. Fixes #3717
-rw-r--r--src/network/networkd-ndisc.c31
1 files changed, 13 insertions, 18 deletions
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index 2a1ba2bac7..d9c18b32a5 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -449,22 +449,24 @@ static void ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
}
STRV_FOREACH(i, l) {
- struct {
- NDiscDNSSL header;
- char domain[strlen(*i)];
- } s;
+ _cleanup_free_ NDiscDNSSL *s;
NDiscDNSSL *x;
- zero(s.header);
- strcpy(s.domain, *i);
+ s = malloc0(ALIGN(sizeof(NDiscDNSSL)) + strlen(*i) + 1);
+ if (!s) {
+ log_oom();
+ return;
+ }
+
+ strcpy(NDISC_DNSSL_DOMAIN(s), *i);
if (lifetime == 0) {
- (void) set_remove(link->ndisc_dnssl, &s);
+ (void) set_remove(link->ndisc_dnssl, s);
link_dirty(link);
continue;
}
- x = set_get(link->ndisc_dnssl, &s);
+ x = set_get(link->ndisc_dnssl, s);
if (x) {
x->valid_until = time_now + lifetime * USEC_PER_SEC;
continue;
@@ -483,22 +485,15 @@ static void ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
return;
}
- x = malloc0(ALIGN(sizeof(NDiscDNSSL)) + strlen(*i) + 1);
- if (!x) {
- log_oom();
- return;
- }
+ s->valid_until = time_now + lifetime * USEC_PER_SEC;
- strcpy(NDISC_DNSSL_DOMAIN(x), *i);
- x->valid_until = time_now + lifetime * USEC_PER_SEC;
-
- r = set_put(link->ndisc_dnssl, x);
+ r = set_put(link->ndisc_dnssl, s);
if (r < 0) {
- free(x);
log_oom();
return;
}
+ s = NULL;
assert(r > 0);
link_dirty(link);
}