summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-12-03 19:57:35 +0100
committerThomas Haller <thaller@redhat.com>2022-12-06 17:10:42 +0100
commit5d86db699bc9c549bf1cd23574f8990a762f60e3 (patch)
tree6082c9b2b7407de496555d2bd33213d1e3c731ba
parent53d1d8ba91252fa545bd7d8779af3d3f88ef61e4 (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.c35
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