Commit 8315c22e authored by John Sperbeck's avatar John Sperbeck Committed by Greg Kroah-Hartman

mm/slab.c: fix SLAB freelist randomization duplicate entries

commit c4e490cf upstream.

This patch fixes a bug in the freelist randomization code.  When a high
random number is used, the freelist will contain duplicate entries.  It
will result in different allocations sharing the same chunk.

It will result in odd behaviours and crashes.  It should be uncommon but
it depends on the machines.  We saw it happening more often on some
machines (every few hours of running tests).

Fixes: c7ce4f60 ("mm: SLAB freelist randomization")
Link: http://lkml.kernel.org/r/20170103181908.143178-1-thgarnie@google.comSigned-off-by: default avatarJohn Sperbeck <jsperbeck@google.com>
Signed-off-by: default avatarThomas Garnier <thgarnie@google.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6ca29ee3
...@@ -2475,7 +2475,6 @@ union freelist_init_state { ...@@ -2475,7 +2475,6 @@ union freelist_init_state {
unsigned int pos; unsigned int pos;
unsigned int *list; unsigned int *list;
unsigned int count; unsigned int count;
unsigned int rand;
}; };
struct rnd_state rnd_state; struct rnd_state rnd_state;
}; };
...@@ -2501,8 +2500,7 @@ static bool freelist_state_initialize(union freelist_init_state *state, ...@@ -2501,8 +2500,7 @@ static bool freelist_state_initialize(union freelist_init_state *state,
} else { } else {
state->list = cachep->random_seq; state->list = cachep->random_seq;
state->count = count; state->count = count;
state->pos = 0; state->pos = rand % count;
state->rand = rand;
ret = true; ret = true;
} }
return ret; return ret;
...@@ -2511,7 +2509,9 @@ static bool freelist_state_initialize(union freelist_init_state *state, ...@@ -2511,7 +2509,9 @@ static bool freelist_state_initialize(union freelist_init_state *state,
/* Get the next entry on the list and randomize it using a random shift */ /* Get the next entry on the list and randomize it using a random shift */
static freelist_idx_t next_random_slot(union freelist_init_state *state) static freelist_idx_t next_random_slot(union freelist_init_state *state)
{ {
return (state->list[state->pos++] + state->rand) % state->count; if (state->pos >= state->count)
state->pos = 0;
return state->list[state->pos++];
} }
/* Swap two freelist entries */ /* Swap two freelist entries */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment