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