diff options
Diffstat (limited to 'mm/kasan/quarantine.c')
-rw-r--r-- | mm/kasan/quarantine.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/mm/kasan/quarantine.c b/mm/kasan/quarantine.c index 8fb71e11df3f..55783125a767 100644 --- a/mm/kasan/quarantine.c +++ b/mm/kasan/quarantine.c @@ -137,7 +137,12 @@ static void qlink_free(struct qlist_node *qlink, struct kmem_cache *cache) if (IS_ENABLED(CONFIG_SLAB)) local_irq_save(flags); + /* + * As the object now gets freed from the quaratine, assume that its + * free track is no longer valid. + */ *(u8 *)kasan_mem_to_shadow(object) = KASAN_KMALLOC_FREE; + ___cache_free(cache, object, _THIS_IP_); if (IS_ENABLED(CONFIG_SLAB)) @@ -163,7 +168,7 @@ static void qlist_free_all(struct qlist_head *q, struct kmem_cache *cache) qlist_init(q); } -void quarantine_put(struct kmem_cache *cache, void *object) +bool quarantine_put(struct kmem_cache *cache, void *object) { unsigned long flags; struct qlist_head *q; @@ -171,6 +176,13 @@ void quarantine_put(struct kmem_cache *cache, void *object) struct kasan_free_meta *meta = kasan_get_free_meta(cache, object); /* + * If there's no metadata for this object, don't put it into + * quarantine. + */ + if (!meta) + return false; + + /* * Note: irq must be disabled until after we move the batch to the * global quarantine. Otherwise quarantine_remove_cache() can miss * some objects belonging to the cache if they are in our local temp @@ -183,7 +195,7 @@ void quarantine_put(struct kmem_cache *cache, void *object) q = this_cpu_ptr(&cpu_quarantine); if (q->offline) { local_irq_restore(flags); - return; + return false; } qlist_put(q, &meta->quarantine_link, cache->size); if (unlikely(q->bytes > QUARANTINE_PERCPU_SIZE)) { @@ -206,6 +218,8 @@ void quarantine_put(struct kmem_cache *cache, void *object) } local_irq_restore(flags); + + return true; } void quarantine_reduce(void) |