diff mbox series

[1/9] mm: kmemleak: properly disable task stack scanning

Message ID 20230123170419.7292-2-george@enfabrica.net (mailing list archive)
State New
Headers show
Series mm: kmemleak: fix unreported memory leaks | expand

Commit Message

George Prekas Jan. 23, 2023, 5:04 p.m. UTC
kmemleak has a flag to enable or disable task stack scanning.
Unfortunately, this flag does not work as intended. Even when the user
disables stack scanning, kmemleak will scan them. Stacks are allocated
with vmalloc and are included in the list of objects to scan of
kmemleak.

Introduce a new function kmemleak_mark_stack that marks an allocation as
a stack. This allows kmemleak to properly decide whether to scan or not
the object based on the respective flag.

Signed-off-by: George Prekas <george@enfabrica.net>
---
 include/linux/kmemleak.h |  1 +
 kernel/fork.c            |  3 +++
 mm/kmemleak.c            | 39 ++++++++++++++++++++++-----------------
 3 files changed, 26 insertions(+), 17 deletions(-)

Comments

kernel test robot Jan. 24, 2023, 12:39 a.m. UTC | #1
Hi George,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on vbabka-slab/for-next]
[also build test ERROR on linus/master v6.2-rc5 next-20230123]
[cannot apply to akpm-mm/mm-everything]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/George-Prekas/mm-kmemleak-properly-disable-task-stack-scanning/20230124-010911
base:   git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git for-next
patch link:    https://lore.kernel.org/r/20230123170419.7292-2-george%40enfabrica.net
patch subject: [PATCH 1/9] mm: kmemleak: properly disable task stack scanning
config: s390-defconfig (https://download.01.org/0day-ci/archive/20230124/202301240827.j2GJi7v5-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/f0d9df4305849ecea4402bc614cadb0dd357da77
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review George-Prekas/mm-kmemleak-properly-disable-task-stack-scanning/20230124-010911
        git checkout f0d9df4305849ecea4402bc614cadb0dd357da77
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   kernel/fork.c: In function 'alloc_thread_stack_node':
>> kernel/fork.c:320:9: error: implicit declaration of function 'kmemleak_mark_stack'; did you mean 'kmemleak_no_scan'? [-Werror=implicit-function-declaration]
     320 |         kmemleak_mark_stack(stack);
         |         ^~~~~~~~~~~~~~~~~~~
         |         kmemleak_no_scan
   kernel/fork.c: At top level:
   kernel/fork.c:865:20: warning: no previous prototype for 'arch_task_cache_init' [-Wmissing-prototypes]
     865 | void __init __weak arch_task_cache_init(void) { }
         |                    ^~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +320 kernel/fork.c

   274	
   275	static int alloc_thread_stack_node(struct task_struct *tsk, int node)
   276	{
   277		struct vm_struct *vm;
   278		void *stack;
   279		int i;
   280	
   281		for (i = 0; i < NR_CACHED_STACKS; i++) {
   282			struct vm_struct *s;
   283	
   284			s = this_cpu_xchg(cached_stacks[i], NULL);
   285	
   286			if (!s)
   287				continue;
   288	
   289			/* Reset stack metadata. */
   290			kasan_unpoison_range(s->addr, THREAD_SIZE);
   291	
   292			stack = kasan_reset_tag(s->addr);
   293	
   294			/* Clear stale pointers from reused stack. */
   295			memset(stack, 0, THREAD_SIZE);
   296	
   297			if (memcg_charge_kernel_stack(s)) {
   298				vfree(s->addr);
   299				return -ENOMEM;
   300			}
   301	
   302			tsk->stack_vm_area = s;
   303			tsk->stack = stack;
   304			return 0;
   305		}
   306	
   307		/*
   308		 * Allocated stacks are cached and later reused by new threads,
   309		 * so memcg accounting is performed manually on assigning/releasing
   310		 * stacks to tasks. Drop __GFP_ACCOUNT.
   311		 */
   312		stack = __vmalloc_node_range(THREAD_SIZE, THREAD_ALIGN,
   313					     VMALLOC_START, VMALLOC_END,
   314					     THREADINFO_GFP & ~__GFP_ACCOUNT,
   315					     PAGE_KERNEL,
   316					     0, node, __builtin_return_address(0));
   317		if (!stack)
   318			return -ENOMEM;
   319	
 > 320		kmemleak_mark_stack(stack);
   321	
   322		vm = find_vm_area(stack);
   323		if (memcg_charge_kernel_stack(vm)) {
   324			vfree(stack);
   325			return -ENOMEM;
   326		}
   327		/*
   328		 * We can't call find_vm_area() in interrupt context, and
   329		 * free_thread_stack() can be called in interrupt context,
   330		 * so cache the vm_struct.
   331		 */
   332		tsk->stack_vm_area = vm;
   333		stack = kasan_reset_tag(stack);
   334		tsk->stack = stack;
   335		return 0;
   336	}
   337
kernel test robot Jan. 24, 2023, 5:46 a.m. UTC | #2
Hi George,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on vbabka-slab/for-next]
[also build test WARNING on linus/master v6.2-rc5 next-20230123]
[cannot apply to akpm-mm/mm-everything]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/George-Prekas/mm-kmemleak-properly-disable-task-stack-scanning/20230124-010911
base:   git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git for-next
patch link:    https://lore.kernel.org/r/20230123170419.7292-2-george%40enfabrica.net
patch subject: [PATCH 1/9] mm: kmemleak: properly disable task stack scanning
config: arc-randconfig-r043-20230123 (https://download.01.org/0day-ci/archive/20230124/202301241355.ytFzL2p6-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/f0d9df4305849ecea4402bc614cadb0dd357da77
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review George-Prekas/mm-kmemleak-properly-disable-task-stack-scanning/20230124-010911
        git checkout f0d9df4305849ecea4402bc614cadb0dd357da77
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   mm/kmemleak.c: In function 'kmemleak_mark_stack':
>> mm/kmemleak.c:1244:46: warning: passing argument 1 of 'find_and_get_object' makes integer from pointer without a cast [-Wint-conversion]
    1244 |                 object = find_and_get_object(ptr, 0);
         |                                              ^~~
         |                                              |
         |                                              const void *
   mm/kmemleak.c:561:66: note: expected 'long unsigned int' but argument is of type 'const void *'
     561 | static struct kmemleak_object *find_and_get_object(unsigned long ptr, int alias)
         |                                                    ~~~~~~~~~~~~~~^~~


vim +/find_and_get_object +1244 mm/kmemleak.c

  1233	
  1234	/**
  1235	 * kmemleak_mark_stack - mark the allocated object as a kernel stack
  1236	 *
  1237	 * @ptr:	pointer to beginning of the object
  1238	 */
  1239	void __ref kmemleak_mark_stack(const void *ptr)
  1240	{
  1241		struct kmemleak_object *object;
  1242	
  1243		if (kmemleak_enabled && ptr && !IS_ERR(ptr)) {
> 1244			object = find_and_get_object(ptr, 0);
  1245			if (object) {
  1246				object->flags |= OBJECT_STACK;
  1247				put_object(object);
  1248			}
  1249		}
  1250	}
  1251
kernel test robot Jan. 24, 2023, 5:57 a.m. UTC | #3
Hi George,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on vbabka-slab/for-next]
[also build test ERROR on linus/master v6.2-rc5]
[cannot apply to akpm-mm/mm-everything]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/George-Prekas/mm-kmemleak-properly-disable-task-stack-scanning/20230124-010911
base:   git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git for-next
patch link:    https://lore.kernel.org/r/20230123170419.7292-2-george%40enfabrica.net
patch subject: [PATCH 1/9] mm: kmemleak: properly disable task stack scanning
config: riscv-randconfig-r042-20230123 (https://download.01.org/0day-ci/archive/20230124/202301241309.4F6LhLvK-lkp@intel.com/config)
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 4196ca3278f78c6e19246e54ab0ecb364e37d66a)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/f0d9df4305849ecea4402bc614cadb0dd357da77
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review George-Prekas/mm-kmemleak-properly-disable-task-stack-scanning/20230124-010911
        git checkout f0d9df4305849ecea4402bc614cadb0dd357da77
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   kernel/fork.c:163:13: warning: no previous prototype for function 'arch_release_task_struct' [-Wmissing-prototypes]
   void __weak arch_release_task_struct(struct task_struct *tsk)
               ^
   kernel/fork.c:163:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void __weak arch_release_task_struct(struct task_struct *tsk)
   ^
   static 
>> kernel/fork.c:320:2: error: call to undeclared function 'kmemleak_mark_stack'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
           kmemleak_mark_stack(stack);
           ^
   kernel/fork.c:865:20: warning: no previous prototype for function 'arch_task_cache_init' [-Wmissing-prototypes]
   void __init __weak arch_task_cache_init(void) { }
                      ^
   kernel/fork.c:865:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void __init __weak arch_task_cache_init(void) { }
   ^
   static 
   2 warnings and 1 error generated.


vim +/kmemleak_mark_stack +320 kernel/fork.c

   274	
   275	static int alloc_thread_stack_node(struct task_struct *tsk, int node)
   276	{
   277		struct vm_struct *vm;
   278		void *stack;
   279		int i;
   280	
   281		for (i = 0; i < NR_CACHED_STACKS; i++) {
   282			struct vm_struct *s;
   283	
   284			s = this_cpu_xchg(cached_stacks[i], NULL);
   285	
   286			if (!s)
   287				continue;
   288	
   289			/* Reset stack metadata. */
   290			kasan_unpoison_range(s->addr, THREAD_SIZE);
   291	
   292			stack = kasan_reset_tag(s->addr);
   293	
   294			/* Clear stale pointers from reused stack. */
   295			memset(stack, 0, THREAD_SIZE);
   296	
   297			if (memcg_charge_kernel_stack(s)) {
   298				vfree(s->addr);
   299				return -ENOMEM;
   300			}
   301	
   302			tsk->stack_vm_area = s;
   303			tsk->stack = stack;
   304			return 0;
   305		}
   306	
   307		/*
   308		 * Allocated stacks are cached and later reused by new threads,
   309		 * so memcg accounting is performed manually on assigning/releasing
   310		 * stacks to tasks. Drop __GFP_ACCOUNT.
   311		 */
   312		stack = __vmalloc_node_range(THREAD_SIZE, THREAD_ALIGN,
   313					     VMALLOC_START, VMALLOC_END,
   314					     THREADINFO_GFP & ~__GFP_ACCOUNT,
   315					     PAGE_KERNEL,
   316					     0, node, __builtin_return_address(0));
   317		if (!stack)
   318			return -ENOMEM;
   319	
 > 320		kmemleak_mark_stack(stack);
   321	
   322		vm = find_vm_area(stack);
   323		if (memcg_charge_kernel_stack(vm)) {
   324			vfree(stack);
   325			return -ENOMEM;
   326		}
   327		/*
   328		 * We can't call find_vm_area() in interrupt context, and
   329		 * free_thread_stack() can be called in interrupt context,
   330		 * so cache the vm_struct.
   331		 */
   332		tsk->stack_vm_area = vm;
   333		stack = kasan_reset_tag(stack);
   334		tsk->stack = stack;
   335		return 0;
   336	}
   337
kernel test robot Jan. 24, 2023, 6:07 a.m. UTC | #4
Hi George,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on vbabka-slab/for-next]
[also build test ERROR on linus/master v6.2-rc5 next-20230124]
[cannot apply to akpm-mm/mm-everything]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/George-Prekas/mm-kmemleak-properly-disable-task-stack-scanning/20230124-010911
base:   git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git for-next
patch link:    https://lore.kernel.org/r/20230123170419.7292-2-george%40enfabrica.net
patch subject: [PATCH 1/9] mm: kmemleak: properly disable task stack scanning
config: s390-randconfig-r044-20230123 (https://download.01.org/0day-ci/archive/20230124/202301241343.blMmgE7L-lkp@intel.com/config)
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 4196ca3278f78c6e19246e54ab0ecb364e37d66a)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/f0d9df4305849ecea4402bc614cadb0dd357da77
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review George-Prekas/mm-kmemleak-properly-disable-task-stack-scanning/20230124-010911
        git checkout f0d9df4305849ecea4402bc614cadb0dd357da77
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=s390 olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from mm/kmemleak.c:85:
   In file included from include/linux/memblock.h:13:
   In file included from arch/s390/include/asm/dma.h:5:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __raw_readb(PCI_IOBASE + addr);
                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:37:59: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
                                                             ^
   include/uapi/linux/swab.h:102:54: note: expanded from macro '__swab16'
   #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
                                                        ^
   In file included from mm/kmemleak.c:85:
   In file included from include/linux/memblock.h:13:
   In file included from arch/s390/include/asm/dma.h:5:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:35:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:115:54: note: expanded from macro '__swab32'
   #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
                                                        ^
   In file included from mm/kmemleak.c:85:
   In file included from include/linux/memblock.h:13:
   In file included from arch/s390/include/asm/dma.h:5:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:692:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:700:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:708:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:717:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:726:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:735:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
>> mm/kmemleak.c:1244:32: error: incompatible pointer to integer conversion passing 'const void *' to parameter of type 'unsigned long' [-Wint-conversion]
                   object = find_and_get_object(ptr, 0);
                                                ^~~
   mm/kmemleak.c:561:66: note: passing argument to parameter 'ptr' here
   static struct kmemleak_object *find_and_get_object(unsigned long ptr, int alias)
                                                                    ^
   12 warnings and 1 error generated.


vim +1244 mm/kmemleak.c

  1233	
  1234	/**
  1235	 * kmemleak_mark_stack - mark the allocated object as a kernel stack
  1236	 *
  1237	 * @ptr:	pointer to beginning of the object
  1238	 */
  1239	void __ref kmemleak_mark_stack(const void *ptr)
  1240	{
  1241		struct kmemleak_object *object;
  1242	
  1243		if (kmemleak_enabled && ptr && !IS_ERR(ptr)) {
> 1244			object = find_and_get_object(ptr, 0);
  1245			if (object) {
  1246				object->flags |= OBJECT_STACK;
  1247				put_object(object);
  1248			}
  1249		}
  1250	}
  1251
Catalin Marinas Jan. 25, 2023, 2:47 p.m. UTC | #5
On Mon, Jan 23, 2023 at 11:04:11AM -0600, George Prekas wrote:
> @@ -1586,23 +1608,6 @@ static void kmemleak_scan(void)
>  	}
>  	put_online_mems();
>  
> -	/*
> -	 * Scanning the task stacks (may introduce false negatives).
> -	 */
> -	if (kmemleak_stack_scan) {
> -		struct task_struct *p, *g;
> -
> -		rcu_read_lock();
> -		for_each_process_thread(g, p) {
> -			void *stack = try_get_task_stack(p);
> -			if (stack) {
> -				scan_block(stack, stack + THREAD_SIZE, NULL);
> -				put_task_stack(p);
> -			}
> -		}
> -		rcu_read_unlock();
> -	}

On architectures without VMAP_STACK, we still need the above otherwise
it could lead to some false positives.
kernel test robot Feb. 1, 2023, 3:38 p.m. UTC | #6
Hi George,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on vbabka-slab/for-next]
[also build test WARNING on linus/master v6.2-rc6]
[cannot apply to akpm-mm/mm-everything]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/George-Prekas/mm-kmemleak-properly-disable-task-stack-scanning/20230124-010911
base:   git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git for-next
patch link:    https://lore.kernel.org/r/20230123170419.7292-2-george%40enfabrica.net
patch subject: [PATCH 1/9] mm: kmemleak: properly disable task stack scanning
config: s390-randconfig-s051-20230129 (https://download.01.org/0day-ci/archive/20230201/202302012338.O1vnQ1Ar-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 12.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-39-gce1a6720-dirty
        # https://github.com/intel-lab-lkp/linux/commit/f0d9df4305849ecea4402bc614cadb0dd357da77
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review George-Prekas/mm-kmemleak-properly-disable-task-stack-scanning/20230124-010911
        git checkout f0d9df4305849ecea4402bc614cadb0dd357da77
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=s390 olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=s390 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

sparse warnings: (new ones prefixed by >>)
>> mm/kmemleak.c:1244:46: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected unsigned long ptr @@     got void const *ptr @@
   mm/kmemleak.c:1244:46: sparse:     expected unsigned long ptr
   mm/kmemleak.c:1244:46: sparse:     got void const *ptr
   mm/kmemleak.c:1772:13: sparse: sparse: context imbalance in 'kmemleak_seq_start' - different lock contexts for basic block
   mm/kmemleak.c: note: in included file (through include/linux/rculist.h, include/linux/sched/signal.h):
   include/linux/rcupdate.h:795:9: sparse: sparse: context imbalance in 'kmemleak_seq_stop' - unexpected unlock

vim +1244 mm/kmemleak.c

  1233	
  1234	/**
  1235	 * kmemleak_mark_stack - mark the allocated object as a kernel stack
  1236	 *
  1237	 * @ptr:	pointer to beginning of the object
  1238	 */
  1239	void __ref kmemleak_mark_stack(const void *ptr)
  1240	{
  1241		struct kmemleak_object *object;
  1242	
  1243		if (kmemleak_enabled && ptr && !IS_ERR(ptr)) {
> 1244			object = find_and_get_object(ptr, 0);
  1245			if (object) {
  1246				object->flags |= OBJECT_STACK;
  1247				put_object(object);
  1248			}
  1249		}
  1250	}
  1251
diff mbox series

Patch

diff --git a/include/linux/kmemleak.h b/include/linux/kmemleak.h
index 6a3cd1bf4680..1e2e8deac6dc 100644
--- a/include/linux/kmemleak.h
+++ b/include/linux/kmemleak.h
@@ -33,6 +33,7 @@  extern void kmemleak_alloc_phys(phys_addr_t phys, size_t size,
 				gfp_t gfp) __ref;
 extern void kmemleak_free_part_phys(phys_addr_t phys, size_t size) __ref;
 extern void kmemleak_ignore_phys(phys_addr_t phys) __ref;
+extern void kmemleak_mark_stack(const void *ptr) __ref;
 
 static inline void kmemleak_alloc_recursive(const void *ptr, size_t size,
 					    int min_count, slab_flags_t flags,
diff --git a/kernel/fork.c b/kernel/fork.c
index 9f7fe3541897..e66337ce88d4 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -97,6 +97,7 @@ 
 #include <linux/io_uring.h>
 #include <linux/bpf.h>
 #include <linux/stackprotector.h>
+#include <linux/kmemleak.h>
 
 #include <asm/pgalloc.h>
 #include <linux/uaccess.h>
@@ -316,6 +317,8 @@  static int alloc_thread_stack_node(struct task_struct *tsk, int node)
 	if (!stack)
 		return -ENOMEM;
 
+	kmemleak_mark_stack(stack);
+
 	vm = find_vm_area(stack);
 	if (memcg_charge_kernel_stack(vm)) {
 		vfree(stack);
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 92f670edbf51..b40735539abd 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -176,6 +176,8 @@  struct kmemleak_object {
 #define OBJECT_FULL_SCAN	(1 << 3)
 /* flag set for object allocated with physical address */
 #define OBJECT_PHYS		(1 << 4)
+/* flag set by alloc_thread_stack_node for stacks */
+#define OBJECT_STACK		(1 << 5)
 
 #define HEX_PREFIX		"    "
 /* number of bytes to print per line; must be 16 or 32 */
@@ -1229,6 +1231,24 @@  void __ref kmemleak_ignore_phys(phys_addr_t phys)
 }
 EXPORT_SYMBOL(kmemleak_ignore_phys);
 
+/**
+ * kmemleak_mark_stack - mark the allocated object as a kernel stack
+ *
+ * @ptr:	pointer to beginning of the object
+ */
+void __ref kmemleak_mark_stack(const void *ptr)
+{
+	struct kmemleak_object *object;
+
+	if (kmemleak_enabled && ptr && !IS_ERR(ptr)) {
+		object = find_and_get_object(ptr, 0);
+		if (object) {
+			object->flags |= OBJECT_STACK;
+			put_object(object);
+		}
+	}
+}
+
 /*
  * Update an object's checksum and return true if it was modified.
  */
@@ -1404,6 +1424,8 @@  static void scan_object(struct kmemleak_object *object)
 	if (!(object->flags & OBJECT_ALLOCATED))
 		/* already freed object */
 		goto out;
+	if (!kmemleak_stack_scan && object->flags & OBJECT_STACK)
+		goto out;
 
 	obj_ptr = object->flags & OBJECT_PHYS ?
 		  __va((phys_addr_t)object->pointer) :
@@ -1586,23 +1608,6 @@  static void kmemleak_scan(void)
 	}
 	put_online_mems();
 
-	/*
-	 * Scanning the task stacks (may introduce false negatives).
-	 */
-	if (kmemleak_stack_scan) {
-		struct task_struct *p, *g;
-
-		rcu_read_lock();
-		for_each_process_thread(g, p) {
-			void *stack = try_get_task_stack(p);
-			if (stack) {
-				scan_block(stack, stack + THREAD_SIZE, NULL);
-				put_task_stack(p);
-			}
-		}
-		rcu_read_unlock();
-	}
-
 	/*
 	 * Scan the objects already referenced from the sections scanned
 	 * above.