]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network-ndisc: avoid VLAs (#3725)
authorDaniel Mack <github@zonque.org>
Fri, 15 Jul 2016 02:56:11 +0000 (04:56 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 15 Jul 2016 02:56:11 +0000 (22:56 -0400)
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

src/network/networkd-ndisc.c

index 2a1ba2bac7fe37c485dfb01d99dd02c02b7c752e..d9c18b32a5f8b2f323635627886902bc7a131613 100644 (file)
@@ -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);
         }