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 | |
| 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.
| -rw-r--r-- | accel-pppd/extra/ipv6pool.c | 13 | ||||
| -rw-r--r-- | accel-pppd/ifcfg.c | 4 | ||||
| -rw-r--r-- | accel-pppd/ipdb.c | 11 | ||||
| -rw-r--r-- | accel-pppd/ppp/ipv6cp_opt_intfid.c | 9 |
4 files changed, 25 insertions, 12 deletions
diff --git a/accel-pppd/extra/ipv6pool.c b/accel-pppd/extra/ipv6pool.c index 9a763445..05b84fe8 100644 --- a/accel-pppd/extra/ipv6pool.c +++ b/accel-pppd/extra/ipv6pool.c @@ -293,11 +293,18 @@ static void add_prefix(struct ip6_pool *pool, const char *_val) /* end = start | hostmask(mask) (matches the original generator) */ memcpy(&end, &start, sizeof(end)); - if (mask > 64) - *(uint64_t *)(end.s6_addr + 8) = htobe64(be64toh(*(uint64_t *)(end.s6_addr + 8)) | ((1llu << (128 - mask)) - 1)); + if (mask > 64) { + uint64_t value; + memcpy(&value, end.s6_addr + 8, sizeof(value)); + value = htobe64(be64toh(value) | ((1llu << (128 - mask)) - 1)); + memcpy(end.s6_addr + 8, &value, sizeof(value)); + } else { + uint64_t value; memset(end.s6_addr + 8, 0xff, 8); - *(uint64_t *)end.s6_addr = htobe64(be64toh(*(uint64_t *)end.s6_addr) | ((1llu << (64 - mask)) - 1)); + memcpy(&value, end.s6_addr, sizeof(value)); + value = htobe64(be64toh(value) | ((1llu << (64 - mask)) - 1)); + memcpy(end.s6_addr, &value, sizeof(value)); } { diff --git a/accel-pppd/ifcfg.c b/accel-pppd/ifcfg.c index 4e4a381a..66f5cc6b 100644 --- a/accel-pppd/ifcfg.c +++ b/accel-pppd/ifcfg.c @@ -225,7 +225,7 @@ void __export ap_session_ifdown(struct ap_session *ses) if (ses->ctrl->ppp) { ifr6.ifr6_addr.s6_addr32[0] = htonl(0xfe800000); - *(uint64_t *)(ifr6.ifr6_addr.s6_addr + 8) = ses->ipv6->intf_id; + memcpy(ifr6.ifr6_addr.s6_addr + 8, &ses->ipv6->intf_id, sizeof(ses->ipv6->intf_id)); ifr6.ifr6_prefixlen = 64; net->sock6_ioctl(SIOCDIFADDR, &ifr6); } @@ -376,4 +376,4 @@ int __export ap_session_vrf(struct ap_session *ses, const char *vrf_name, int le return 0; } -#endif
\ No newline at end of file +#endif 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)); + } } diff --git a/accel-pppd/ppp/ipv6cp_opt_intfid.c b/accel-pppd/ppp/ipv6cp_opt_intfid.c index cb33f024..5de88932 100644 --- a/accel-pppd/ppp/ipv6cp_opt_intfid.c +++ b/accel-pppd/ppp/ipv6cp_opt_intfid.c @@ -284,12 +284,14 @@ static void ipaddr_print(void (*print)(const char *fmt,...), struct ipv6cp_optio { struct ipaddr_option_t *ipaddr_opt = container_of(opt, typeof(*ipaddr_opt), opt); struct ipv6cp_opt64_t *opt64 = (struct ipv6cp_opt64_t *)ptr; - struct in6_addr a; + struct in6_addr a = {}; + uint64_t intf_id; if (ptr) - *(uint64_t *)(a.s6_addr + 8) = opt64->val; + intf_id = opt64->val; else - *(uint64_t *)(a.s6_addr + 8) = ipaddr_opt->ppp->ses.ipv6->intf_id; + intf_id = ipaddr_opt->ppp->ses.ipv6->intf_id; + memcpy(a.s6_addr + 8, &intf_id, sizeof(intf_id)); print("<addr %x:%x:%x:%x>", ntohs(a.s6_addr16[4]), ntohs(a.s6_addr16[5]), ntohs(a.s6_addr16[6]), ntohs(a.s6_addr16[7])); } @@ -376,4 +378,3 @@ static void init() } DEFINE_INIT(5, init); - |
