diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-09-01 08:50:35 +0300 |
|---|---|---|
| committer | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-09-01 08:55:54 +0300 |
| commit | 004ec5adc7e5702c518583caef437d304932beb5 (patch) | |
| tree | 68517316725b0fcad7fe302f6ace4ccee9ed682e /accel-pppd/ipdb.c | |
| parent | cbbae583e584f83957acd99440fc67343d46b800 (diff) | |
| download | accel-ppp-004ec5adc7e5702c518583caef437d304932beb5.tar.gz accel-ppp-004ec5adc7e5702c518583caef437d304932beb5.zip | |
ipv6: avoid integer access through address bytes
Copy interface IDs and prefix words between aligned temporaries and byte arrays instead of casting IPv6 address storage to uint64_t pointers.
Diffstat (limited to 'accel-pppd/ipdb.c')
| -rw-r--r-- | accel-pppd/ipdb.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/accel-pppd/ipdb.c b/accel-pppd/ipdb.c index 8fc08063..264f67b3 100644 --- a/accel-pppd/ipdb.c +++ b/accel-pppd/ipdb.c @@ -75,18 +75,23 @@ void __export ipdb_put_ipv6_prefix(struct ap_session *ses, struct ipv6db_prefix_ void __export build_ip6_addr(struct ipv6db_addr_t *a, uint64_t intf_id, struct in6_addr *addr) { + uint64_t value; + memcpy(addr, &a->addr, sizeof(*addr)); if (a->prefix_len == 128) return; if (a->prefix_len <= 64) - *(uint64_t *)(addr->s6_addr + 8) = intf_id; - else + memcpy(addr->s6_addr + 8, &intf_id, sizeof(intf_id)); + else { /* prefix_len 65..127 means a shift of up to 63 bits: a plain * int literal 1 is undefined behavior for shifts >= 31, so the * host bits mask must be built from a 64-bit constant */ - *(uint64_t *)(addr->s6_addr + 8) |= intf_id & htobe64((UINT64_C(1) << (128 - a->prefix_len)) - 1); + memcpy(&value, addr->s6_addr + 8, sizeof(value)); + value |= intf_id & htobe64((UINT64_C(1) << (128 - a->prefix_len)) - 1); + memcpy(addr->s6_addr + 8, &value, sizeof(value)); + } } |
