slab: Fix misplaced __free_one()
Subsystems (3)
PATCH 1/1 slab: Fix misplaced __free_one()
The implementation of __free_one() was accidentally placed inside a CONFIG_NUMA #ifdef. Move it above.
Reported-by Randy Dunlap <[email protected]>
Signed-off-by Kees Cook <[email protected]>
---
This a fix for slab-add-naive-detection-of-double-free.patch
--- mm/slab.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
mm/slab.c +10 -10
@@ -588,6 +588,16 @@ static int transfer_objects(struct array_cache *to,return nr; } +/* &alien->lock must be held by alien callers. */ +static __always_inline void __free_one(struct array_cache *ac, void *objp) +{ +/* Avoid trivial double-free. */ +if (IS_ENABLED (CONFIG_SLAB_FREELIST_HARDENED ) && +WARN_ON_ONCE (ac->avail >0 && ac->entry[ac->avail -1 ] == objp)) +return ; + ac->entry[ac->avail++] = objp; +} +#ifndef CONFIG_NUMA #define drain_alien_cache (cachep, alien) do { } while (0)
@@ -749,16 +759,6 @@ static void drain_alien_cache(struct kmem_cache *cachep, } } -/* &alien->lock must be held by alien callers. */ -static __always_inline void __free_one(struct array_cache *ac, void *objp) -{ -/* Avoid trivial double-free. */ -if (IS_ENABLED (CONFIG_SLAB_FREELIST_HARDENED ) && -WARN_ON_ONCE (ac->avail >0 && ac->entry[ac->avail -1 ] == objp)) -return ; - ac->entry[ac->avail++] = objp; -} -static int __cache_free_alien (struct kmem_cache *cachep,void *objp,int node,int page_node) {
Signature · 5 lines
2.25.1 -- Kees Cook
Quoted 6 lines · Kees Cook
The implementation of
__free_one()was accidentally placed inside aCONFIG_NUMA#ifdef. Move it above.Reported-by Randy Dunlap <[email protected]>Signed-off-by Kees Cook <[email protected]>
Thanks.
Quoted 45 lines
---
This a fix for slab-add-naive-detection-of-double-free.patch--- mm/slab.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)mm/slab.c +10
-10@@ -588,6 +588,16 @@ static int transfer_objects(struct array_cache *to,return nr; } +/* &alien->lock must be held by alien callers. */ +static __always_inline void __free_one(struct array_cache *ac, void *objp) +{ +/* Avoid trivial double-free. */ +if (IS_ENABLED (CONFIG_SLAB_FREELIST_HARDENED ) && +WARN_ON_ONCE (ac->avail >0 && ac->entry[ac->avail -1 ] == objp)) +return ; + ac->entry[ac->avail++] = objp; +} +#ifndef CONFIG_NUMA #define drain_alien_cache (cachep, alien) do { } while (0)@@ -749,16 +759,6 @@ static void drain_alien_cache(struct kmem_cache *cachep, } } -/* &alien->lock must be held by alien callers. */ -static __always_inline void __free_one(struct array_cache *ac, void *objp) -{ -/* Avoid trivial double-free. */ -if (IS_ENABLED (CONFIG_SLAB_FREELIST_HARDENED ) && -WARN_ON_ONCE (ac->avail >0 && ac->entry[ac->avail -1 ] == objp)) -return ; - ac->entry[ac->avail++] = objp; -} -static int __cache_free_alien (struct kmem_cache *cachep,void *objp,int node,int page_node) {
Signature · 1 line
~Randy
Hi Kees,
Quoted 7 lines · On Fri, 26 Jun 2020 13:07:53 -0700 Kees Cook <[email protected]> wrote:
The implementation of
__free_one()was accidentally placed inside aCONFIG_NUMA#ifdef. Move it above.Reported-by Randy Dunlap <[email protected]>Signed-off-by Kees Cook <[email protected]>
I added that to linux-next for today.
Signature · 2 lines
Cheers, Stephen Rothwell