about summary refs log tree commit diff
path: root/src/systemd
diff options
context:
space:
mode:
authorSebastien Bacher <seb128@ubuntu.com>2018-12-10 18:50:07 +0100
committerSebastien Bacher <seb128@ubuntu.com>2018-12-10 21:58:19 +0100
commite335b8ae803a5a0f28a692edc0349ababa490445 (patch)
tree753f3d62d0aaa2ab6a831f8dcfa525d714868d0c /src/systemd
parent69385b013384918a005052098d5beae003b4c8d3 (diff)
parent227c401a10a930af6fd5f123aef345fcd130d6aa (diff)
Import Debian changes 1.12.6-0ubuntu1
network-manager (1.12.6-0ubuntu1) disco; urgency=medium

  * New upstream version
    - Fix a vulnerability in the internal DHCPv6 client (CVE-2018-15688).
  * debian/patches/git_mac_change.patch:
    - backported a regression fix from upstream git

  [ Alfonso Sanchez-Beato ]
  * Import some WoWLAN patches from the newer stable serie (LP: #1781597)
Diffstat (limited to 'src/systemd')
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-network.c2
-rw-r--r--src/systemd/src/libsystemd-network/dhcp6-internal.h2
-rw-r--r--src/systemd/src/libsystemd-network/dhcp6-option.c87
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-client.c2
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-lease.c2
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-client.c15
6 files changed, 55 insertions, 55 deletions
diff --git a/src/systemd/src/libsystemd-network/dhcp-network.c b/src/systemd/src/libsystemd-network/dhcp-network.c
index 90fe29d0..80e9577c 100644
--- a/src/systemd/src/libsystemd-network/dhcp-network.c
+++ b/src/systemd/src/libsystemd-network/dhcp-network.c
@@ -128,8 +128,6 @@ int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
         const uint8_t *bcast_addr = NULL;
         uint8_t dhcp_hlen = 0;
 
-        assert_return(mac_addr_len > 0, -EINVAL);
-
         if (arp_type == ARPHRD_ETHER) {
                 assert_return(mac_addr_len == ETH_ALEN, -EINVAL);
                 memcpy(&eth_mac, mac_addr, ETH_ALEN);
diff --git a/src/systemd/src/libsystemd-network/dhcp6-internal.h b/src/systemd/src/libsystemd-network/dhcp6-internal.h
index f1cbd6a4..06e2e532 100644
--- a/src/systemd/src/libsystemd-network/dhcp6-internal.h
+++ b/src/systemd/src/libsystemd-network/dhcp6-internal.h
@@ -91,7 +91,7 @@ int dhcp6_option_append_pd(uint8_t *buf, size_t len, DHCP6IA *pd);
 int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
 int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
                        size_t *optlen, uint8_t **optvalue);
-int dhcp6_option_parse_status(DHCP6Option *option);
+int dhcp6_option_parse_status(DHCP6Option *option, size_t len);
 int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia);
 int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
                                 struct in6_addr **addrs, size_t count,
diff --git a/src/systemd/src/libsystemd-network/dhcp6-option.c b/src/systemd/src/libsystemd-network/dhcp6-option.c
index a8a56463..22970443 100644
--- a/src/systemd/src/libsystemd-network/dhcp6-option.c
+++ b/src/systemd/src/libsystemd-network/dhcp6-option.c
@@ -105,7 +105,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
                 return -EINVAL;
         }
 
-        if (*buflen < len)
+        if (*buflen < offsetof(DHCP6Option, data) + len)
                 return -ENOBUFS;
 
         ia_hdr = *buf;
@@ -249,10 +249,11 @@ int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
         return 0;
 }
 
-int dhcp6_option_parse_status(DHCP6Option *option) {
+int dhcp6_option_parse_status(DHCP6Option *option, size_t len) {
         DHCP6StatusOption *statusopt = (DHCP6StatusOption *)option;
 
-        if (be16toh(option->len) + sizeof(DHCP6Option) < sizeof(*statusopt))
+        if (len < sizeof(DHCP6StatusOption) ||
+            be16toh(option->len) + sizeof(DHCP6Option) < sizeof(DHCP6StatusOption))
                 return -ENOBUFS;
 
         return be16toh(statusopt->status);
@@ -279,7 +280,7 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia,
         }
 
         if (be16toh(option->len) + sizeof(DHCP6Option) > sizeof(*addr_option)) {
-                r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options);
+                r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options, be16toh(option->len) + sizeof(DHCP6Option) - sizeof(*addr_option));
                 if (r != 0)
                         return r < 0 ? r: 0;
         }
@@ -319,7 +320,7 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia,
         }
 
         if (be16toh(option->len) + sizeof(DHCP6Option) > sizeof(*pdprefix_option)) {
-                r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options);
+                r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options, be16toh(option->len) + sizeof(DHCP6Option) - sizeof(*pdprefix_option));
                 if (r != 0)
                         return r < 0 ? r: 0;
         }
@@ -464,13 +465,15 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
 
                 case SD_DHCP6_OPTION_STATUS_CODE:
 
-                        status = dhcp6_option_parse_status(option);
-                        if (status) {
+                        status = dhcp6_option_parse_status(option, optlen + sizeof(DHCP6Option));
+                        if (status < 0) {
+                                r = status;
+                                goto error;
+                        }
+                        if (status > 0) {
                                 log_dhcp6_client(client, "IA status %d",
                                                  status);
 
-                                dhcp6_lease_free_ia(ia);
-
                                 r = -EINVAL;
                                 goto error;
                         }
@@ -552,6 +555,7 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
                 bool first = true;
 
                 for (;;) {
+                        const char *label;
                         uint8_t c;
 
                         c = optval[pos++];
@@ -559,47 +563,41 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
                         if (c == 0)
                                 /* End of name */
                                 break;
-                        else if (c <= 63) {
-                                const char *label;
-
-                                /* Literal label */
-                                label = (const char *)&optval[pos];
-                                pos += c;
-                                if (pos > optlen)
-                                        return -EMSGSIZE;
-
-                                if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
-
-                                if (first)
-                                        first = false;
-                                else
-                                        ret[n++] = '.';
-
-                                r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
-                                if (r < 0)
-                                        goto fail;
-
-                                n += r;
-                                continue;
-                        } else {
-                                r = -EBADMSG;
-                                goto fail;
-                        }
-                }
+                        if (c > 63)
+                                return -EBADMSG;
+
+                        /* Literal label */
+                        label = (const char *)&optval[pos];
+                        pos += c;
+                        if (pos >= optlen)
+                                return -EMSGSIZE;
+
+                        if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
+                                return -ENOMEM;
+
+                        if (first)
+                                first = false;
+                        else
+                                ret[n++] = '.';
 
-                if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
-                        r = -ENOMEM;
-                        goto fail;
+                        r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
+                        if (r < 0)
+                                return r;
+
+                        n += r;
                 }
 
+                if (n == 0)
+                        continue;
+
+                if (!GREEDY_REALLOC(ret, allocated, n + 1))
+                        return -ENOMEM;
+
                 ret[n] = 0;
 
                 r = strv_extend(&names, ret);
                 if (r < 0)
-                        goto fail;
+                        return r;
 
                 idx++;
         }
@@ -607,7 +605,4 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
         *str_arr = TAKE_PTR(names);
 
         return idx;
-
-fail:
-        return r;
 }
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
index c2f81e1c..c2802541 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
@@ -1649,6 +1649,8 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
                         client->timeout_resend =
                                 sd_event_source_unref(client->timeout_resend);
 
+                        client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
+
                         r = client_initialize(client);
                         if (r < 0)
                                 goto error;
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
index 33a0796a..841d0792 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
@@ -279,6 +279,8 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
                 free(option);
         }
 
+        free(lease->root_path);
+        free(lease->timezone);
         free(lease->hostname);
         free(lease->domainname);
         free(lease->dns);
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
index ca03f580..5641c545 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
@@ -776,8 +776,8 @@ static int client_parse_message(
                 uint8_t *optval;
                 be32_t iaid_lease;
 
-                if (len < offsetof(DHCP6Option, data) ||
-                    len < offsetof(DHCP6Option, data) + be16toh(option->len))
+                if (len < pos + offsetof(DHCP6Option, data) ||
+                    len < pos + offsetof(DHCP6Option, data) + be16toh(option->len))
                         return -ENOBUFS;
 
                 optcode = be16toh(option->code);
@@ -828,13 +828,14 @@ static int client_parse_message(
                         break;
 
                 case SD_DHCP6_OPTION_STATUS_CODE:
-                        status = dhcp6_option_parse_status(option);
-                        if (status) {
+                        status = dhcp6_option_parse_status(option, optlen + sizeof(DHCP6Option));
+                        if (status < 0)
+                                return status;
+
+                        if (status > 0) {
                                 log_dhcp6_client(client, "%s Status %s",
                                                  dhcp6_message_type_to_string(message->type),
                                                  dhcp6_message_status_to_string(status));
-                                dhcp6_lease_free_ia(&lease->ia);
-                                dhcp6_lease_free_ia(&lease->pd);
 
                                 return -EINVAL;
                         }
@@ -1233,6 +1234,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
                 log_dhcp6_client(client, "T1 expires in %s",
                                  format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC));
 
+                client->lease->ia.timeout_t1 = sd_event_source_unref(client->lease->ia.timeout_t1);
                 r = sd_event_add_time(client->event,
                                       &client->lease->ia.timeout_t1,
                                       clock_boottime_or_monotonic(), time_now + timeout,
@@ -1255,6 +1257,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
                 log_dhcp6_client(client, "T2 expires in %s",
                                  format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC));
 
+                client->lease->ia.timeout_t2 = sd_event_source_unref(client->lease->ia.timeout_t2);
                 r = sd_event_add_time(client->event,
                                       &client->lease->ia.timeout_t2,
                                       clock_boottime_or_monotonic(), time_now + timeout,