Message ID | 20190109090628.1695-1-rocking@whu.edu.cn (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mm/slub.c: re-randomize random_seq if necessary | expand |
On Wed, Jan 09, 2019 at 05:06:27PM +0800, Peng Wang wrote: > calculate_sizes() could be called in several places > like (red_zone/poison/order/store_user)_store() while > random_seq remains unchanged. > > If random_seq is not NULL in calculate_sizes(), re-randomize it. Why do we want to re-randomise the slab at these points?
On Wednesday, January 9, 2019 8:14 PM, Matthew Wilcox wrote: > On Wed, Jan 09, 2019 at 05:06:27PM +0800, Peng Wang wrote: > > calculate_sizes() could be called in several places > > like (red_zone/poison/order/store_user)_store() while > > random_seq remains unchanged. > > > > If random_seq is not NULL in calculate_sizes(), re-randomize it. > > Why do we want to re-randomise the slab at these points? At these points, s->size might change, but random_seq still use the old size and not updated. When doing shuffle_freelist() in allocat_slab(), old next object offset would be used. idx = s->random_seq[*pos]; One possible case: s->size gets smaller, then number of objects in a slab gets bigger. The size of s->random_seq array should be bigger but not updated. In next_freelist_entry(), *pos might exceed the s->random_seq. When we get zero value from s->random_seq[*pos] twice after exceeding, BUG_ON(object == fp) would be triggered in set_freepointer().
diff --git a/mm/slub.c b/mm/slub.c index 1e3d0ec4e200..2a9d18019545 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3583,6 +3583,15 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order) if (oo_objects(s->oo) > oo_objects(s->max)) s->max = s->oo; +#ifdef CONFIG_SLAB_FREELIST_RANDOM + if (unlikely(s->random_seq)) { + kfree(s->random_seq); + s->random_seq = NULL; + if (init_cache_random_seq(s)) + return 0; + } +#endif + return !!oo_objects(s->oo); }
calculate_sizes() could be called in several places like (red_zone/poison/order/store_user)_store() while random_seq remains unchanged. If random_seq is not NULL in calculate_sizes(), re-randomize it. Signed-off-by: Peng Wang <rocking@whu.edu.cn> --- mm/slub.c | 9 +++++++++ 1 file changed, 9 insertions(+)