Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

kasan: skip quarantine if object is still accessible under RCU

Currently, enabling KASAN masks bugs where a lockless lookup path gets a
pointer to a SLAB_TYPESAFE_BY_RCU object that might concurrently be
recycled and is insufficiently careful about handling recycled objects:
KASAN puts freed objects in SLAB_TYPESAFE_BY_RCU slabs onto its quarantine
queues, even when it can't actually detect UAF in these objects, and the
quarantine prevents fast recycling.

When I introduced CONFIG_SLUB_RCU_DEBUG, my intention was that enabling
CONFIG_SLUB_RCU_DEBUG should cause KASAN to mark such objects as freed
after an RCU grace period and put them on the quarantine, while disabling
CONFIG_SLUB_RCU_DEBUG should allow such objects to be reused immediately;
but that hasn't actually been working.

I discovered such a UAF bug involving SLAB_TYPESAFE_BY_RCU yesterday; I
could only trigger this bug in a KASAN build by disabling
CONFIG_SLUB_RCU_DEBUG and applying this patch.

Link: https://lkml.kernel.org/r/20250723-kasan-tsbrcu-noquarantine-v1-1-846c8645976c@google.com
Signed-off-by: Jann Horn <jannh@google.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Reviewed-by: Alexander Potapenko <glider@google.com>
Acked-by: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Dmitriy Vyukov <dvyukov@google.com>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Jann Horn and committed by
Andrew Morton
56bdf83d d171b10b

+18 -7
+18 -7
mm/kasan/common.c
··· 230 230 } 231 231 232 232 static inline void poison_slab_object(struct kmem_cache *cache, void *object, 233 - bool init, bool still_accessible) 233 + bool init) 234 234 { 235 235 void *tagged_object = object; 236 236 237 237 object = kasan_reset_tag(object); 238 - 239 - /* RCU slabs could be legally used after free within the RCU period. */ 240 - if (unlikely(still_accessible)) 241 - return; 242 238 243 239 kasan_poison(object, round_up(cache->object_size, KASAN_GRANULE_SIZE), 244 240 KASAN_SLAB_FREE, init); ··· 257 261 if (!kasan_arch_is_ready() || is_kfence_address(object)) 258 262 return false; 259 263 260 - poison_slab_object(cache, object, init, still_accessible); 264 + /* 265 + * If this point is reached with an object that must still be 266 + * accessible under RCU, we can't poison it; in that case, also skip the 267 + * quarantine. This should mostly only happen when CONFIG_SLUB_RCU_DEBUG 268 + * has been disabled manually. 269 + * 270 + * Putting the object on the quarantine wouldn't help catch UAFs (since 271 + * we can't poison it here), and it would mask bugs caused by 272 + * SLAB_TYPESAFE_BY_RCU users not being careful enough about object 273 + * reuse; so overall, putting the object into the quarantine here would 274 + * be counterproductive. 275 + */ 276 + if (still_accessible) 277 + return false; 278 + 279 + poison_slab_object(cache, object, init); 261 280 262 281 /* 263 282 * If the object is put into quarantine, do not let slab put the object ··· 530 519 if (check_slab_allocation(slab->slab_cache, ptr, ip)) 531 520 return false; 532 521 533 - poison_slab_object(slab->slab_cache, ptr, false, false); 522 + poison_slab_object(slab->slab_cache, ptr, false); 534 523 return true; 535 524 } 536 525