Skip to content

Commit 18e5066

Browse files
xairytorvalds
authored andcommitted
kasan, slub: fix conflicts with CONFIG_SLAB_FREELIST_HARDENED
CONFIG_SLAB_FREELIST_HARDENED hashes freelist pointer with the address of the object where the pointer gets stored. With tag based KASAN we don't account for that when building freelist, as we call set_freepointer() with the first argument untagged. This patch changes the code to properly propagate tags throughout the loop. Link: http://lkml.kernel.org/r/3df171559c52201376f246bf7ce3184fe21c1dc7.1549921721.git.andreyknvl@google.com Signed-off-by: Andrey Konovalov <andreyknvl@google.com> Reported-by: Qian Cai <cai@lca.pw> Cc: Andrey Ryabinin <aryabinin@virtuozzo.com> Cc: Alexander Potapenko <glider@google.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Catalin Marinas <catalin.marinas@arm.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> Cc: Vincenzo Frascino <vincenzo.frascino@arm.com> Cc: Kostya Serebryany <kcc@google.com> Cc: Evgeniy Stepanov <eugenis@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent a710122 commit 18e5066

File tree

1 file changed

+7
-13
lines changed

1 file changed

+7
-13
lines changed

mm/slub.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,6 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
303303
__p < (__addr) + (__objects) * (__s)->size; \
304304
__p += (__s)->size)
305305

306-
#define for_each_object_idx(__p, __idx, __s, __addr, __objects) \
307-
for (__p = fixup_red_left(__s, __addr), __idx = 1; \
308-
__idx <= __objects; \
309-
__p += (__s)->size, __idx++)
310-
311306
/* Determine object index from a given position */
312307
static inline unsigned int slab_index(void *p, struct kmem_cache *s, void *addr)
313308
{
@@ -1664,17 +1659,16 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
16641659
shuffle = shuffle_freelist(s, page);
16651660

16661661
if (!shuffle) {
1667-
for_each_object_idx(p, idx, s, start, page->objects) {
1668-
if (likely(idx < page->objects)) {
1669-
next = p + s->size;
1670-
next = setup_object(s, page, next);
1671-
set_freepointer(s, p, next);
1672-
} else
1673-
set_freepointer(s, p, NULL);
1674-
}
16751662
start = fixup_red_left(s, start);
16761663
start = setup_object(s, page, start);
16771664
page->freelist = start;
1665+
for (idx = 0, p = start; idx < page->objects - 1; idx++) {
1666+
next = p + s->size;
1667+
next = setup_object(s, page, next);
1668+
set_freepointer(s, p, next);
1669+
p = next;
1670+
}
1671+
set_freepointer(s, p, NULL);
16781672
}
16791673

16801674
page->inuse = page->objects;

0 commit comments

Comments
 (0)