Skip to content

Commit b06952c

Browse files
committed
mm/slub: remove redundant kasan_reset_tag() from freelist_ptr calculations
Commit d36a63a ("kasan, slub: fix more conflicts with CONFIG_SLAB_FREELIST_HARDENED") has introduced kasan_reset_tags() to freelist_ptr() encoding/decoding when CONFIG_SLAB_FREELIST_HARDENED is enabled to resolve issues when passing tagged or untagged pointers inconsistently would lead to incorrect calculations. Later, commit aa1ef4d ("kasan, mm: reset tags when accessing metadata") made sure all pointers have tags reset regardless of CONFIG_SLAB_FREELIST_HARDENED, because there was no other way to access the freepointer metadata safely with hw tag-based KASAN. Therefore the kasan_reset_tag() usage in freelist_ptr_encode()/decode() is now redundant, as all callers use kasan_reset_tag() unconditionally when constructing ptr_addr. Remove the redundant calls and simplify the code and remove obsolete comments. Also in freelist_ptr_encode() introduce an 'encoded' variable to make the lines shorter and make it similar to the _decode() one. Signed-off-by: Vlastimil Babka <[email protected]> Reviewed-by: Andrey Konovalov <[email protected]> Acked-by: Kees Cook <[email protected]>
1 parent 44f6a42 commit b06952c

File tree

1 file changed

+6
-16
lines changed

1 file changed

+6
-16
lines changed

mm/slub.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -374,22 +374,14 @@ typedef struct { unsigned long v; } freeptr_t;
374374
static inline freeptr_t freelist_ptr_encode(const struct kmem_cache *s,
375375
void *ptr, unsigned long ptr_addr)
376376
{
377+
unsigned long encoded;
378+
377379
#ifdef CONFIG_SLAB_FREELIST_HARDENED
378-
/*
379-
* When CONFIG_KASAN_SW/HW_TAGS is enabled, ptr_addr might be tagged.
380-
* Normally, this doesn't cause any issues, as both set_freepointer()
381-
* and get_freepointer() are called with a pointer with the same tag.
382-
* However, there are some issues with CONFIG_SLUB_DEBUG code. For
383-
* example, when __free_slub() iterates over objects in a cache, it
384-
* passes untagged pointers to check_object(). check_object() in turns
385-
* calls get_freepointer() with an untagged pointer, which causes the
386-
* freepointer to be restored incorrectly.
387-
*/
388-
return (freeptr_t){.v = (unsigned long)ptr ^ s->random ^
389-
swab((unsigned long)kasan_reset_tag((void *)ptr_addr))};
380+
encoded = (unsigned long)ptr ^ s->random ^ swab(ptr_addr);
390381
#else
391-
return (freeptr_t){.v = (unsigned long)ptr};
382+
encoded = (unsigned long)ptr;
392383
#endif
384+
return (freeptr_t){.v = encoded};
393385
}
394386

395387
static inline void *freelist_ptr_decode(const struct kmem_cache *s,
@@ -398,9 +390,7 @@ static inline void *freelist_ptr_decode(const struct kmem_cache *s,
398390
void *decoded;
399391

400392
#ifdef CONFIG_SLAB_FREELIST_HARDENED
401-
/* See the comment in freelist_ptr_encode */
402-
decoded = (void *)(ptr.v ^ s->random ^
403-
swab((unsigned long)kasan_reset_tag((void *)ptr_addr)));
393+
decoded = (void *)(ptr.v ^ s->random ^ swab(ptr_addr));
404394
#else
405395
decoded = (void *)ptr.v;
406396
#endif

0 commit comments

Comments
 (0)