From 8a8005f7ca8973702b36e711993bfff89ca9600c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 28 Jan 2016 04:33:48 +0000 Subject: [PATCH] Add padding between odhcp6c_entry structures to ensure 32-bit alignment struct odhcp6c_entry is not declared as __packed, so the compiler may assume it is naturally aligned. Signed-off-by: Ben Hutchings --- src/odhcp6c.c | 16 +++++++++------- src/odhcp6c.h | 8 ++++++++ src/ra.c | 5 +++-- src/script.c | 5 +++-- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/odhcp6c.c b/src/odhcp6c.c index 59f6390..ba568bd 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -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; @@ -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; } @@ -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; @@ -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); } } } diff --git a/src/odhcp6c.h b/src/odhcp6c.h index 928f82f..98d91dd 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -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; diff --git a/src/ra.c b/src/ra.c index 1c121e6..2d442f6 100644 --- a/src/ra.c +++ b/src/ra.c @@ -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; diff --git a/src/script.c b/src/script.c index 1533510..72add21 100644 --- a/src/script.c +++ b/src/script.c @@ -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++ = ' '; } -- 2.25.1