summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-09-01 08:50:35 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-09-01 08:55:54 +0300
commit004ec5adc7e5702c518583caef437d304932beb5 (patch)
tree68517316725b0fcad7fe302f6ace4ccee9ed682e
parentcbbae583e584f83957acd99440fc67343d46b800 (diff)
downloadaccel-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.c13
-rw-r--r--accel-pppd/ifcfg.c4
-rw-r--r--accel-pppd/ipdb.c11
-rw-r--r--accel-pppd/ppp/ipv6cp_opt_intfid.c9
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);
-