Patch "mm/slub: fix stack overruns with SLUB_STATS" has been added to the 4.14-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    mm/slub: fix stack overruns with SLUB_STATS

to the 4.14-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     mm-slub-fix-stack-overruns-with-slub_stats.patch
and it can be found in the queue-4.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit df8b4708b18129dde2c37f021b813db9f14cd639
Author: Qian Cai <cai@xxxxxx>
Date:   Mon Jun 1 21:45:57 2020 -0700

    mm/slub: fix stack overruns with SLUB_STATS
    
    [ Upstream commit a68ee0573991e90af2f1785db309206408bad3e5 ]
    
    There is no need to copy SLUB_STATS items from root memcg cache to new
    memcg cache copies.  Doing so could result in stack overruns because the
    store function only accepts 0 to clear the stat and returns an error for
    everything else while the show method would print out the whole stat.
    
    Then, the mismatch of the lengths returns from show and store methods
    happens in memcg_propagate_slab_attrs():
    
            else if (root_cache->max_attr_size < ARRAY_SIZE(mbuf))
                    buf = mbuf;
    
    max_attr_size is only 2 from slab_attr_store(), then, it uses mbuf[64]
    in show_stat() later where a bounch of sprintf() would overrun the stack
    variable.  Fix it by always allocating a page of buffer to be used in
    show_stat() if SLUB_STATS=y which should only be used for debug purpose.
    
      # echo 1 > /sys/kernel/slab/fs_cache/shrink
      BUG: KASAN: stack-out-of-bounds in number+0x421/0x6e0
      Write of size 1 at addr ffffc900256cfde0 by task kworker/76:0/53251
    
      Hardware name: HPE ProLiant DL385 Gen10/ProLiant DL385 Gen10, BIOS A40 07/10/2019
      Workqueue: memcg_kmem_cache memcg_kmem_cache_create_func
      Call Trace:
        number+0x421/0x6e0
        vsnprintf+0x451/0x8e0
        sprintf+0x9e/0xd0
        show_stat+0x124/0x1d0
        alloc_slowpath_show+0x13/0x20
        __kmem_cache_create+0x47a/0x6b0
    
      addr ffffc900256cfde0 is located in stack of task kworker/76:0/53251 at offset 0 in frame:
       process_one_work+0x0/0xb90
    
      this frame has 1 object:
       [32, 72) 'lockdep_map'
    
      Memory state around the buggy address:
       ffffc900256cfc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       ffffc900256cfd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      >ffffc900256cfd80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
                                                             ^
       ffffc900256cfe00: 00 00 00 00 00 f2 f2 f2 00 00 00 00 00 00 00 00
       ffffc900256cfe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      ==================================================================
      Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: __kmem_cache_create+0x6ac/0x6b0
      Workqueue: memcg_kmem_cache memcg_kmem_cache_create_func
      Call Trace:
        __kmem_cache_create+0x6ac/0x6b0
    
    Fixes: 107dab5c92d5 ("slub: slub-specific propagation changes")
    Signed-off-by: Qian Cai <cai@xxxxxx>
    Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
    Cc: Glauber Costa <glauber@xxxxxxxxxxxx>
    Cc: Christoph Lameter <cl@xxxxxxxxx>
    Cc: Pekka Enberg <penberg@xxxxxxxxxx>
    Cc: David Rientjes <rientjes@xxxxxxxxxx>
    Cc: Joonsoo Kim <iamjoonsoo.kim@xxxxxxx>
    Link: http://lkml.kernel.org/r/20200429222356.4322-1-cai@xxxxxx
    Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/mm/slub.c b/mm/slub.c
index 66b7987129337..09d4cc4391bb2 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -5601,7 +5601,8 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s)
 		 */
 		if (buffer)
 			buf = buffer;
-		else if (root_cache->max_attr_size < ARRAY_SIZE(mbuf))
+		else if (root_cache->max_attr_size < ARRAY_SIZE(mbuf) &&
+			 !IS_ENABLED(CONFIG_SLUB_STATS))
 			buf = mbuf;
 		else {
 			buffer = (char *) get_zeroed_page(GFP_KERNEL);



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux