Skip to content

Commit

Permalink
BUG/MEDIUM: Make sure stksess is properly aligned.
Browse files Browse the repository at this point in the history
When we allocate struct stksess, we also allocate memory to store the
associated data before the struct itself.
As the data can be of different types, they can have different size. However,
we need the struct stksess to be properly aligned, as it can do 64bits
load/store (including atomic load/stores) on 64bits platforms, and some of
them doesn't support unaligned access.
So, when allocating the struct stksess, round the size up to the next
multiple of sizeof(void *), and make sure the struct stksess itself is
properly aligned.
Many thanks to Paul Martin for investigating and reporting that bug.

This should be backported to earlier releases.
  • Loading branch information
Olivier Houchard authored and wtarreau committed Nov 15, 2018
1 parent a8b2671 commit 52dabbc
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/stick_table.c
Expand Up @@ -45,14 +45,15 @@
/* structure used to return a table key built from a sample */
static THREAD_LOCAL struct stktable_key static_table_key;

#define round_ptr_size(i) (((i) + (sizeof(void *) - 1)) &~ (sizeof(void *) - 1))
/*
* Free an allocated sticky session <ts>, and decrease sticky sessions counter
* in table <t>.
*/
void __stksess_free(struct stktable *t, struct stksess *ts)
{
t->current--;
pool_free(t->pool, (void *)ts - t->data_size);
pool_free(t->pool, (void *)ts - round_ptr_size(t->data_size));
}

/*
Expand Down Expand Up @@ -230,7 +231,7 @@ struct stksess *__stksess_new(struct stktable *t, struct stktable_key *key)
ts = pool_alloc(t->pool);
if (ts) {
t->current++;
ts = (void *)ts + t->data_size;
ts = (void *)ts + round_ptr_size(t->data_size);
__stksess_init(t, ts);
if (key)
stksess_setkey(t, ts, key);
Expand Down Expand Up @@ -598,7 +599,7 @@ int stktable_init(struct stktable *t)
t->updates = EB_ROOT_UNIQUE;
HA_SPIN_INIT(&t->lock);

t->pool = create_pool("sticktables", sizeof(struct stksess) + t->data_size + t->key_size, MEM_F_SHARED);
t->pool = create_pool("sticktables", sizeof(struct stksess) + round_ptr_size(t->data_size) + t->key_size, MEM_F_SHARED);

t->exp_next = TICK_ETERNITY;
if ( t->expire ) {
Expand Down

0 comments on commit 52dabbc

Please sign in to comment.