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:
parent
b433300e4c
commit
e4336c0a5d
@ -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;
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user