mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-26 21:40:08 +01:00
initrd: fix out-of-bounds read when detecting address family in dt_get_ipaddr_property()
The @family argument is an input and output argument. Initially, the family is set to AF_UNSPEC, in which case the family gets detected based on the IP address. However, we call dt_get_ipaddr_property() multiple times to parse the netmask, the gateway and the IP address. That means, after the first successfull call, the @family is set to AF_INET or AF_INET6. Note that the previous code (in the switch block) would only check that the family is set to AF_UNSPEC, but it would not check that the @family matches the expected binary address length @len. Later, we then might call nm_ip_address_new_binary() with a family and a binary address of unexpected length. Also drop the error checking for nm_ip_address_new_binary(). nm_ip_address_new_binary() can only fail if the prefix length is larger than 32/128. The function has no way to validate the input arguments beyond that and can thus not fail (short of undefined behavior).
This commit is contained in:
parent
e7cf22be3e
commit
9618f1bb4b
1 changed files with 7 additions and 23 deletions
|
|
@ -51,40 +51,24 @@ dt_get_ipaddr_property (const char *base,
|
|||
const char *prop,
|
||||
int *family)
|
||||
{
|
||||
NMIPAddress *addr;
|
||||
gs_free char *buf = NULL;
|
||||
size_t len;
|
||||
gs_free_error GError *error = NULL;
|
||||
int f;
|
||||
|
||||
if (!dt_get_property (base, dev, prop, &buf, &len))
|
||||
return NULL;
|
||||
|
||||
switch (len) {
|
||||
case 4:
|
||||
if (*family == AF_UNSPEC)
|
||||
*family = AF_INET;
|
||||
break;
|
||||
case 16:
|
||||
if (*family == AF_UNSPEC)
|
||||
*family = AF_INET6;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (*family == AF_UNSPEC) {
|
||||
f = nm_utils_addr_family_from_size (len);
|
||||
if ( f == AF_UNSPEC
|
||||
|| ( *family != AF_UNSPEC
|
||||
&& *family != f)) {
|
||||
_LOGW (LOGD_CORE, "%s: Address %s has unrecognized length (%zd)",
|
||||
dev, prop, len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addr = nm_ip_address_new_binary (*family, buf, 0, &error);
|
||||
if (!addr) {
|
||||
_LOGW (LOGD_CORE, "%s: Address %s is malformed: %s",
|
||||
dev, prop, error->message);
|
||||
}
|
||||
|
||||
return addr;
|
||||
*family = f;
|
||||
return nm_ip_address_new_binary (f, buf, 0, NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue