diff options
author | Thomas Haller <thaller@redhat.com> | 2022-12-03 19:57:35 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-12-06 17:10:42 +0100 |
commit | 5d86db699bc9c549bf1cd23574f8990a762f60e3 (patch) | |
tree | 6082c9b2b7407de496555d2bd33213d1e3c731ba | |
parent | 53d1d8ba91252fa545bd7d8779af3d3f88ef61e4 (diff) |
core: check hardware address length in nm_utils_get_ipv6_interface_identifier()
nm_utils_get_ipv6_interface_identifier() has non-obvious requirements on
the hardware address. If the caller passes a wrong length, it will
trigger an assertion or even cause out of bound read. This would mean
that the caller needs to carefully check the length. Such requirements
on the caller are wrong.
Also, in practice the hardware length comes from platform/kernel. We
don't want to trust that what kernel tells us always has the required
address length, so the caller would always have to double check before
calling the function.
Instead, handle unexpected address lengths.
Fixes: e2270040c0a2 ('core: use Interface Identifiers for IPv6 SLAAC addresses')
Fixes: 1d396e997221 ('core-utils: use 64-bit WPAN address for a 6LoWPAN IID')
-rw-r--r-- | src/core/nm-core-utils.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index 0e375e91d1..9448ba7b03 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -3271,25 +3271,32 @@ nm_utils_get_ipv6_interface_identifier(NMLinkType link_type, * making sure to set the 'u' bit to 1. The GUID is the lower 64 bits * of the IPoIB interface's hardware address. */ - g_return_val_if_fail(hwaddr_len == INFINIBAND_ALEN, FALSE); - memcpy(out_iid->id_u8, hwaddr + INFINIBAND_ALEN - 8, 8); - out_iid->id_u8[0] |= 0x02; - return TRUE; + if (hwaddr_len == INFINIBAND_ALEN) { + memcpy(out_iid->id_u8, hwaddr + INFINIBAND_ALEN - 8, 8); + out_iid->id_u8[0] |= 0x02; + return TRUE; + } + break; case NM_LINK_TYPE_GRE: /* Hardware address is the network-endian IPv4 address */ - g_return_val_if_fail(hwaddr_len == 4, FALSE); - addr = unaligned_read_ne32(hwaddr); - out_iid->id_u8[0] = get_gre_eui64_u_bit(addr); - out_iid->id_u8[1] = 0x00; - out_iid->id_u8[2] = 0x5E; - out_iid->id_u8[3] = 0xFE; - memcpy(out_iid->id_u8 + 4, &addr, 4); - return TRUE; + if (hwaddr_len == 4) { + addr = unaligned_read_ne32(hwaddr); + out_iid->id_u8[0] = get_gre_eui64_u_bit(addr); + out_iid->id_u8[1] = 0x00; + out_iid->id_u8[2] = 0x5E; + out_iid->id_u8[3] = 0xFE; + memcpy(out_iid->id_u8 + 4, &addr, 4); + return TRUE; + } + break; case NM_LINK_TYPE_6LOWPAN: /* The hardware address is already 64-bit. This is the case for * IEEE 802.15.4 networks. */ - memcpy(out_iid->id_u8, hwaddr, sizeof(out_iid->id_u8)); - return TRUE; + if (hwaddr_len == sizeof(out_iid->id_u8)) { + memcpy(out_iid->id_u8, hwaddr, sizeof(out_iid->id_u8)); + return TRUE; + } + break; default: if (hwaddr_len == ETH_ALEN) { /* Translate 48-bit MAC address to a 64-bit Modified EUI-64. See |