summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-09-01 08:50:26 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-09-01 08:55:54 +0300
commitcbbae583e584f83957acd99440fc67343d46b800 (patch)
tree4441077a968e713c0fa9b7807f49e7dd45efc4ee
parente0c63e6259bb4a75468e5680fb2d10934c2d035b (diff)
downloadaccel-ppp-cbbae583e584f83957acd99440fc67343d46b800.tar.gz
accel-ppp-cbbae583e584f83957acd99440fc67343d46b800.zip
backup: restore scalar fields alignment-safely
Use memcpy for scalar backup headers and restored session, pool, and RADIUS values because variable-length tags do not guarantee native integer alignment.
-rw-r--r--accel-pppd/backup/backup_file.c8
-rw-r--r--accel-pppd/extra/ippool.c4
-rw-r--r--accel-pppd/radius/backup.c40
-rw-r--r--accel-pppd/session_backup.c11
4 files changed, 45 insertions, 18 deletions
diff --git a/accel-pppd/backup/backup_file.c b/accel-pppd/backup/backup_file.c
index 472694f0..eaaf87d2 100644
--- a/accel-pppd/backup/backup_file.c
+++ b/accel-pppd/backup/backup_file.c
@@ -96,7 +96,7 @@ static int fs_commit(struct backup_data *d)
ptr = (uint8_t *)(tag + 1);
*ptr = tag->id; ptr++;
*ptr = tag->internal ? 1 : 0; ptr++;
- *(uint16_t *)ptr = tag->size;
+ memcpy(ptr, &tag->size, sizeof(tag->size));
MD5_Update(&md5, tag + 1, 4 + tag->size);
iov[i].iov_base = tag + 1;
iov[i].iov_len = 4 + tag->size;
@@ -278,14 +278,16 @@ static void restore_session(const char *fn, int internal)
}
if (!internal && ptr[1]) {
- ptr += 4 + *(uint16_t *)(ptr + 2);
+ uint16_t tag_size;
+ memcpy(&tag_size, ptr + 2, sizeof(tag_size));
+ ptr += 4 + tag_size;
continue;
}
tag = fs_alloc_tag(d, 0);
tag->id = *ptr; ptr++;
tag->internal = (*ptr & 0x01) ? 1 : 0; ptr ++;
- tag->size = *(uint16_t *)ptr; ptr += 2;
+ memcpy(&tag->size, ptr, sizeof(tag->size)); ptr += 2;
tag->data = ptr; ptr += tag->size;
list_add_tail(&tag->entry, &mod->tag_list);
diff --git a/accel-pppd/extra/ippool.c b/accel-pppd/extra/ippool.c
index e935bb4c..28aecd95 100644
--- a/accel-pppd/extra/ippool.c
+++ b/accel-pppd/extra/ippool.c
@@ -736,10 +736,10 @@ static int session_restore(struct ap_session *ses, struct backup_mod *m)
list_for_each_entry(tag, &m->tag_list, entry) {
switch (tag->id) {
case SES_TAG_IPV4_ADDR:
- addr = *(in_addr_t *)tag->data;
+ memcpy(&addr, tag->data, sizeof(addr));
break;
case SES_TAG_IPV4_PEER_ADDR:
- peer_addr = *(in_addr_t *)tag->data;
+ memcpy(&peer_addr, tag->data, sizeof(peer_addr));
break;
}
}
diff --git a/accel-pppd/radius/backup.c b/accel-pppd/radius/backup.c
index 6d4db636..73825336 100644
--- a/accel-pppd/radius/backup.c
+++ b/accel-pppd/radius/backup.c
@@ -22,6 +22,27 @@
#define RAD_TAG_ACCT_SERVER_ADDR 9
#define RAD_TAG_ACCT_SERVER_PORT 10
#define RAD_TAG_IDLE_TIMEOUT 11
+
+static uint16_t backup_read_u16(const void *ptr)
+{
+ uint16_t value;
+ memcpy(&value, ptr, sizeof(value));
+ return value;
+}
+
+static uint32_t backup_read_u32(const void *ptr)
+{
+ uint32_t value;
+ memcpy(&value, ptr, sizeof(value));
+ return value;
+}
+
+static uint64_t backup_read_u64(const void *ptr)
+{
+ uint64_t value;
+ memcpy(&value, ptr, sizeof(value));
+ return value;
+}
#define RAD_TAG_ACCT_USERNAME 12
@@ -94,10 +115,10 @@ static void restore_ipv4_addr(struct ap_session *ses)
list_for_each_entry(tag, &m->tag_list, entry) {
switch (tag->id) {
case SES_TAG_IPV4_ADDR:
- ses->ipv4->addr = *(in_addr_t *)tag->data;
+ ses->ipv4->addr = backup_read_u32(tag->data);
break;
case SES_TAG_IPV4_PEER_ADDR:
- ses->ipv4->peer_addr = *(in_addr_t *)tag->data;
+ ses->ipv4->peer_addr = backup_read_u32(tag->data);
break;
}
}
@@ -121,16 +142,16 @@ void radius_restore_session(struct ap_session *ses, struct radius_pd_t *rpd)
list_for_each_entry(tag, &m->tag_list, entry) {
switch (tag->id) {
case RAD_TAG_INTERIM_INTERVAL:
- rpd->acct_interim_interval = *(uint32_t *)tag->data;
+ rpd->acct_interim_interval = backup_read_u32(tag->data);
break;
case RAD_TAG_INTERIM_JITTER:
- rpd->acct_interim_jitter = *(uint32_t *)tag->data;
+ rpd->acct_interim_jitter = backup_read_u32(tag->data);
break;
case RAD_TAG_SESSION_TIMEOUT:
- rpd->session_timeout.expire_tv.tv_sec = *(uint64_t *)tag->data - ses->start_time;
+ rpd->session_timeout.expire_tv.tv_sec = backup_read_u64(tag->data) - ses->start_time;
break;
case RAD_TAG_IDLE_TIMEOUT:
- rpd->idle_timeout.period = (*(uint32_t *)tag->data) * 1000;
+ rpd->idle_timeout.period = backup_read_u32(tag->data) * 1000;
break;
case RAD_TAG_IPV4_ADDR:
ses->ipv4 = &rpd->ipv4_addr;
@@ -150,16 +171,16 @@ void radius_restore_session(struct ap_session *ses, struct radius_pd_t *rpd)
rpd->attr_state_len = tag->size;
break;
case RAD_TAG_TERMINATION_ACTION:
- rpd->termination_action = *(uint32_t *)tag->data;
+ rpd->termination_action = backup_read_u32(tag->data);
break;
case RAD_TAG_ACCT_USERNAME:
rpd->acct_username = _strndup(tag->data, tag->size);
break;
case RAD_TAG_ACCT_SERVER_ADDR:
- acct_addr = *(in_addr_t *)tag->data;
+ acct_addr = backup_read_u32(tag->data);
break;
case RAD_TAG_ACCT_SERVER_PORT:
- acct_port = *(uint16_t *)tag->data;
+ acct_port = backup_read_u16(tag->data);
break;
}
}
@@ -182,4 +203,3 @@ static void init(void)
}
DEFINE_INIT(100, init);
-
diff --git a/accel-pppd/session_backup.c b/accel-pppd/session_backup.c
index dea5b600..2873136f 100644
--- a/accel-pppd/session_backup.c
+++ b/accel-pppd/session_backup.c
@@ -59,6 +59,8 @@ static int session_save(struct ap_session *ses, struct backup_mod *m)
static int session_restore(struct ap_session *ses, struct backup_mod *m)
{
struct backup_tag *t;
+ time_t start_time;
+ uint32_t ifindex;
list_for_each_entry(t, &m->tag_list, entry) {
switch(t->id) {
@@ -79,11 +81,14 @@ static int session_restore(struct ap_session *ses, struct backup_mod *m)
ses->ifname[t->size] = 0;
break;
case SES_TAG_START_TIME:
- ses->start_time = *(time_t *)t->data;
+ memcpy(&start_time, t->data, sizeof(start_time));
+ ses->start_time = start_time;
break;
case SES_TAG_IFINDEX:
- if (ses->backup->internal)
- ses->ifindex = *(uint32_t *)t->data;
+ if (ses->backup->internal) {
+ memcpy(&ifindex, t->data, sizeof(ifindex));
+ ses->ifindex = ifindex;
+ }
break;
/*case PPP_TAG_FD:
ses->fd = *(int *)t->data;