Skip to content

Commit

Permalink
Add padding between odhcp6c_entry structures to ensure 32-bit alignment
Browse files Browse the repository at this point in the history
struct odhcp6c_entry is not declared as __packed, so the compiler may
assume it is naturally aligned.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
  • Loading branch information
bwhacks committed Jan 28, 2016
1 parent d277ddb commit 8a8005f
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 11 deletions.
16 changes: 9 additions & 7 deletions src/odhcp6c.c
Expand Up @@ -570,8 +570,9 @@ static struct odhcp6c_entry* odhcp6c_find_entry(enum odhcp6c_state state, const
uint8_t *start = odhcp6c_get_state(state, &len);

for (struct odhcp6c_entry *c = (struct odhcp6c_entry*)start;
(uint8_t*)c < &start[len] && &c->auxtarget[c->auxlen] <= &start[len];
c = (struct odhcp6c_entry*)(&c->auxtarget[c->auxlen]))
(uint8_t*)c < &start[len] &&
(uint8_t*)odhcp6c_next_entry(c) <= &start[len];
c = odhcp6c_next_entry(c))
if (!memcmp(c, new, cmplen) && !memcmp(c->auxtarget, new->auxtarget, new->auxlen))
return c;

Expand Down Expand Up @@ -604,10 +605,10 @@ bool odhcp6c_update_entry(enum odhcp6c_state state, struct odhcp6c_entry *new,
x->t2 = new->t2;
x->iaid = new->iaid;
} else {
odhcp6c_add_state(state, new, sizeof(*new) + new->auxlen);
odhcp6c_add_state(state, new, odhcp6c_entry_size(new));
}
} else if (x) {
odhcp6c_remove_state(state, ((uint8_t*)x) - start, sizeof(*x) + x->auxlen);
odhcp6c_remove_state(state, ((uint8_t*)x) - start, odhcp6c_entry_size(x));
}
return true;
}
Expand All @@ -618,7 +619,8 @@ static void odhcp6c_expire_list(enum odhcp6c_state state, uint32_t elapsed)
size_t len;
uint8_t *start = odhcp6c_get_state(state, &len);
for (struct odhcp6c_entry *c = (struct odhcp6c_entry*)start;
(uint8_t*)c < &start[len] && &c->auxtarget[c->auxlen] <= &start[len];
(uint8_t*)c < &start[len] &&
(uint8_t*)odhcp6c_next_entry(c) <= &start[len];
) {
if (c->t1 < elapsed)
c->t1 = 0;
Expand All @@ -641,10 +643,10 @@ static void odhcp6c_expire_list(enum odhcp6c_state state, uint32_t elapsed)
c->valid -= elapsed;

if (!c->valid) {
odhcp6c_remove_state(state, ((uint8_t*)c) - start, sizeof(*c) + c->auxlen);
odhcp6c_remove_state(state, ((uint8_t*)c) - start, odhcp6c_entry_size(c));
start = odhcp6c_get_state(state, &len);
} else {
c = (struct odhcp6c_entry*)(&c->auxtarget[c->auxlen]);
c = odhcp6c_next_entry(c);
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/odhcp6c.h
Expand Up @@ -302,6 +302,14 @@ struct odhcp6c_entry {
uint8_t auxtarget[];
};

// Include padding after auxtarget to align the next entry
#define odhcp6c_entry_size(entry) \
(sizeof(struct odhcp6c_entry) + (((entry)->auxlen + 3) & ~3))

#define odhcp6c_next_entry(entry) \
((struct odhcp6c_entry *)((uint8_t *)(entry) + odhcp6c_entry_size(entry)))


struct odhcp6c_request_prefix {
uint32_t iaid;
uint16_t length;
Expand Down
5 changes: 3 additions & 2 deletions src/ra.c
Expand Up @@ -444,8 +444,9 @@ bool ra_process(void)
size_t ra_dns_len;
uint8_t *start = odhcp6c_get_state(states[i], &ra_dns_len);
for (struct odhcp6c_entry *c = (struct odhcp6c_entry*)start;
(uint8_t*)c < &start[ra_dns_len] && &c->auxtarget[c->auxlen] <= &start[ra_dns_len];
c = (struct odhcp6c_entry*)(&c->auxtarget[c->auxlen]))
(uint8_t*)c < &start[ra_dns_len] &&
(uint8_t*)odhcp6c_next_entry(c) <= &start[ra_dns_len];
c = odhcp6c_next_entry(c))
if (IN6_ARE_ADDR_EQUAL(&c->router, &from.sin6_addr) &&
c->valid > router_valid)
c->valid = router_valid;
Expand Down
5 changes: 3 additions & 2 deletions src/script.c
Expand Up @@ -220,8 +220,9 @@ static void search_to_env(const char *name, const uint8_t *start, size_t len)
*c++ = '=';

for (struct odhcp6c_entry *e = (struct odhcp6c_entry*)start;
(uint8_t*)e < &start[len] && &e->auxtarget[e->auxlen] <= &start[len];
e = (struct odhcp6c_entry*)(&e->auxtarget[e->auxlen])) {
(uint8_t*)e < &start[len] &&
(uint8_t*)odhcp6c_next_entry(e) <= &start[len];
e = odhcp6c_next_entry(e)) {
c = mempcpy(c, e->auxtarget, e->auxlen);
*c++ = ' ';
}
Expand Down

0 comments on commit 8a8005f

Please sign in to comment.