]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp6-client: fix buffer size calculation in dhcp6_option_parse_ip6addrs()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 23 Sep 2021 16:24:52 +0000 (01:24 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 29 Sep 2021 06:29:40 +0000 (15:29 +0900)
GREEDY_REALLOC() takes number of elements, not buffer size.

This also rename dhcp6_option_parse_ip6addrs() to
dhcp6_option_parse_addresses().

src/libsystemd-network/dhcp6-internal.h
src/libsystemd-network/dhcp6-option.c
src/libsystemd-network/sd-dhcp6-lease.c

index 5c24692233f53a58fdbd6045a548bd1d598391c4..ececddf7be16242d05033522162829444cdaa6bb 100644 (file)
@@ -117,8 +117,11 @@ int dhcp6_option_parse_ia(
                 size_t option_data_len,
                 const uint8_t *option_data,
                 DHCP6IA *ret);
-int dhcp6_option_parse_ip6addrs(const uint8_t *optval, uint16_t optlen,
-                                struct in6_addr **addrs, size_t count);
+int dhcp6_option_parse_addresses(
+                const uint8_t *optval,
+                size_t optlen,
+                struct in6_addr **addrs,
+                size_t *count);
 int dhcp6_option_parse_domainname_list(const uint8_t *optval, uint16_t optlen,
                                        char ***str_arr);
 int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char **str);
index 3dd1cb4956d9545ae100c35a9e9f2de27f11fb78..f7afc0df33594f4c47bec13771d8ac8d44b610c9 100644 (file)
@@ -721,20 +721,26 @@ int dhcp6_option_parse_ia(
         return 0;
 }
 
-int dhcp6_option_parse_ip6addrs(const uint8_t *optval, uint16_t optlen,
-                                struct in6_addr **addrs, size_t count) {
+int dhcp6_option_parse_addresses(
+                const uint8_t *optval,
+                size_t optlen,
+                struct in6_addr **addrs,
+                size_t *count) {
+
+        assert(optval);
+        assert(addrs);
+        assert(count);
 
         if (optlen == 0 || optlen % sizeof(struct in6_addr) != 0)
-                return -EINVAL;
+                return -EBADMSG;
 
-        if (!GREEDY_REALLOC(*addrs, count * sizeof(struct in6_addr) + optlen))
+        if (!GREEDY_REALLOC(*addrs, *count + optlen / sizeof(struct in6_addr)))
                 return -ENOMEM;
 
-        memcpy(*addrs + count, optval, optlen);
+        memcpy(*addrs + *count, optval, optlen);
+        *count += optlen / sizeof(struct in6_addr);
 
-        count += optlen / sizeof(struct in6_addr);
-
-        return count;
+        return 0;
 }
 
 static int parse_domain(const uint8_t **data, uint16_t *len, char **out_domain) {
index 6375a225375757c9bf4f93b1f72c530a65ba5463..9c77b146c7bf543a5ecd4a3993de877c348c35aa 100644 (file)
@@ -194,22 +194,13 @@ void sd_dhcp6_lease_reset_pd_prefix_iter(sd_dhcp6_lease *lease) {
 }
 
 int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
-        int r;
-
         assert_return(lease, -EINVAL);
         assert_return(optval, -EINVAL);
 
-        if (!optlen)
+        if (optlen == 0)
                 return 0;
 
-        r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->dns,
-                                        lease->dns_count);
-        if (r < 0)
-                return r;
-
-        lease->dns_count = r;
-
-        return 0;
+        return dhcp6_option_parse_addresses(optval, optlen, &lease->dns, &lease->dns_count);
 }
 
 int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **addrs) {
@@ -281,12 +272,10 @@ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
                         if (sublen != 16)
                                 return 0;
 
-                        r = dhcp6_option_parse_ip6addrs(subval, sublen, &lease->ntp, lease->ntp_count);
+                        r = dhcp6_option_parse_addresses(subval, sublen, &lease->ntp, &lease->ntp_count);
                         if (r < 0)
                                 return r;
 
-                        lease->ntp_count = r;
-
                         break;
 
                 case DHCP6_NTP_SUBOPTION_SRV_FQDN: {
@@ -307,12 +296,10 @@ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
 }
 
 int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
-        int r;
-
         assert_return(lease, -EINVAL);
         assert_return(optval, -EINVAL);
 
-        if (!optlen)
+        if (optlen == 0)
                 return 0;
 
         if (lease->ntp || lease->ntp_fqdn)
@@ -320,14 +307,7 @@ int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen)
 
         /* Using deprecated SNTP information */
 
-        r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->ntp,
-                                        lease->ntp_count);
-        if (r < 0)
-                return r;
-
-        lease->ntp_count = r;
-
-        return 0;
+        return dhcp6_option_parse_addresses(optval, optlen, &lease->ntp, &lease->ntp_count);
 }
 
 int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease,