1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-09-09 17:45:00 +03:00

network: address-generation: mask prefix with prefixlen for safety

This commit is contained in:
Yu Watanabe
2021-10-01 21:19:51 +09:00
parent 98692ff3b8
commit ffb834cb87

View File

@@ -151,15 +151,20 @@ static int generate_stable_private_address(
return 0; return 0;
} }
int ndisc_router_generate_addresses(Link *link, struct in6_addr *address, uint8_t prefixlen, Set **ret) { int ndisc_router_generate_addresses(Link *link, struct in6_addr *prefix, uint8_t prefixlen, Set **ret) {
_cleanup_set_free_free_ Set *addresses = NULL; _cleanup_set_free_free_ Set *addresses = NULL;
struct in6_addr masked;
IPv6Token *j; IPv6Token *j;
int r; int r;
assert(link); assert(link);
assert(address); assert(prefix);
assert(prefixlen > 0 && prefixlen <= 64);
assert(ret); assert(ret);
masked = *prefix;
in6_addr_mask(&masked, prefixlen);
addresses = set_new(&in6_addr_hash_ops); addresses = set_new(&in6_addr_hash_ops);
if (!addresses) if (!addresses)
return log_oom(); return log_oom();
@@ -168,10 +173,10 @@ int ndisc_router_generate_addresses(Link *link, struct in6_addr *address, uint8_
_cleanup_free_ struct in6_addr *new_address = NULL; _cleanup_free_ struct in6_addr *new_address = NULL;
if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE
&& (in6_addr_is_null(&j->prefix) || in6_addr_equal(&j->prefix, address))) { && (in6_addr_is_null(&j->prefix) || in6_addr_equal(&j->prefix, &masked))) {
struct in6_addr addr; struct in6_addr addr;
if (generate_stable_private_address(link, &NDISC_APP_ID, address, &addr) < 0) if (generate_stable_private_address(link, &NDISC_APP_ID, &masked, &addr) < 0)
continue; continue;
new_address = newdup(struct in6_addr, &addr, 1); new_address = newdup(struct in6_addr, &addr, 1);
@@ -183,7 +188,7 @@ int ndisc_router_generate_addresses(Link *link, struct in6_addr *address, uint8_
if (!new_address) if (!new_address)
return log_oom(); return log_oom();
memcpy(new_address->s6_addr, address->s6_addr, 8); memcpy(new_address->s6_addr, masked.s6_addr, 8);
memcpy(new_address->s6_addr + 8, j->prefix.s6_addr + 8, 8); memcpy(new_address->s6_addr + 8, j->prefix.s6_addr + 8, 8);
} }
@@ -206,7 +211,7 @@ int ndisc_router_generate_addresses(Link *link, struct in6_addr *address, uint8_
if (!addr) if (!addr)
return log_oom(); return log_oom();
generate_eui64_address(link, address, addr); generate_eui64_address(link, &masked, addr);
r = set_consume(addresses, addr); r = set_consume(addresses, addr);
if (r < 0) if (r < 0)