1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-22 13:33:56 +03:00

dhcp: length of each user class field must be positive

This also fixes an memory leak when sd_dhcp_client_set_user_class()
is called multiple times.
This commit is contained in:
Yu Watanabe 2021-01-12 21:47:23 +09:00
parent b433300e4c
commit e4336c0a5d
4 changed files with 22 additions and 16 deletions

View File

@ -38,11 +38,14 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
size_t total = 0;
char **s;
if (strv_isempty((char **) optval))
return -EINVAL;
STRV_FOREACH(s, (char **) optval) {
size_t len = strlen(*s);
if (len > 255)
return -ENAMETOOLONG;
if (len > 255 || len == 0)
return -EINVAL;
total += 1 + len;
}
@ -51,14 +54,13 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
return -ENOBUFS;
options[*offset] = code;
options[*offset + 1] = total;
options[*offset + 1] = total;
*offset += 2;
STRV_FOREACH(s, (char **) optval) {
size_t len = strlen(*s);
options[*offset] = len;
memcpy(&options[*offset + 1], *s, len);
*offset += 1 + len;
}

View File

@ -573,22 +573,26 @@ int sd_dhcp_client_set_mud_url(
int sd_dhcp_client_set_user_class(
sd_dhcp_client *client,
const char* const* user_class) {
char * const *user_class) {
_cleanup_strv_free_ char **s = NULL;
char **p;
char * const *p;
char **s = NULL;
STRV_FOREACH(p, (char **) user_class)
if (strlen(*p) > 255)
return -ENAMETOOLONG;
assert_return(client, -EINVAL);
assert_return(!strv_isempty(user_class), -EINVAL);
s = strv_copy((char **) user_class);
STRV_FOREACH(p, user_class) {
size_t n = strlen(*p);
if (n > 255 || n == 0)
return -EINVAL;
}
s = strv_copy(user_class);
if (!s)
return -ENOMEM;
client->user_class = TAKE_PTR(s);
return 0;
return strv_free_and_replace(client->user_class, s);
}
int sd_dhcp_client_set_client_port(

View File

@ -1417,7 +1417,7 @@ int dhcp4_configure(Link *link) {
}
if (link->network->dhcp_user_class) {
r = sd_dhcp_client_set_user_class(link->dhcp_client, (const char **) link->network->dhcp_user_class);
r = sd_dhcp_client_set_user_class(link->dhcp_client, link->network->dhcp_user_class);
if (r < 0)
return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set user class: %m");
}

View File

@ -181,7 +181,7 @@ int sd_dhcp_client_set_mud_url(
const char *mudurl);
int sd_dhcp_client_set_user_class(
sd_dhcp_client *client,
const char* const *user_class);
char * const *user_class);
int sd_dhcp_client_get_lease(
sd_dhcp_client *client,
sd_dhcp_lease **ret);