diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-09-01 08:50:26 +0300 |
|---|---|---|
| committer | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-09-01 08:55:54 +0300 |
| commit | cbbae583e584f83957acd99440fc67343d46b800 (patch) | |
| tree | 4441077a968e713c0fa9b7807f49e7dd45efc4ee | |
| parent | e0c63e6259bb4a75468e5680fb2d10934c2d035b (diff) | |
| download | accel-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.c | 8 | ||||
| -rw-r--r-- | accel-pppd/extra/ippool.c | 4 | ||||
| -rw-r--r-- | accel-pppd/radius/backup.c | 40 | ||||
| -rw-r--r-- | accel-pppd/session_backup.c | 11 |
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; |
