[PATCH v2] locktorture: Fix memory leak in param_set_cpumask()

Wang Liang posted 1 patch 4 months, 2 weeks ago
kernel/locking/locktorture.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
[PATCH v2] locktorture: Fix memory leak in param_set_cpumask()
Posted by Wang Liang 4 months, 2 weeks ago
With CONFIG_CPUMASK_OFFSTACK=y, the 'bind_writers' buffer is allocated via
alloc_cpumask_var() in param_set_cpumask(). But it is not freed, when
setting the module parameter multiple times by sysfs interface or removing
module.

Below kmemleak trace is seen for this issue:

unreferenced object 0xffff888100aabff8 (size 8):
  comm "bash", pid 323, jiffies 4295059233
  hex dump (first 8 bytes):
    07 00 00 00 00 00 00 00                          ........
  backtrace (crc ac50919):
    __kmalloc_node_noprof+0x2e5/0x420
    alloc_cpumask_var_node+0x1f/0x30
    param_set_cpumask+0x26/0xb0 [locktorture]
    param_attr_store+0x93/0x100
    module_attr_store+0x1b/0x30
    kernfs_fop_write_iter+0x114/0x1b0
    vfs_write+0x300/0x410
    ksys_write+0x60/0xd0
    do_syscall_64+0xa4/0x260
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

This issue can be reproduced by:
  insmod locktorture.ko bind_writers=1
  rmmod locktorture

or:
  insmod locktorture.ko bind_writers=1
  echo 2 > /sys/module/locktorture/parameters/bind_writers

Considering that setting the module parameter 'bind_writers' or
'bind_readers' by sysfs interface has no real effect, set the parameter
permissions to 0444. To fix the memory leak when removing module, free
'bind_writers' and 'bind_readers' memory in lock_torture_cleanup().

Fixes: 73e341242483 ("locktorture: Add readers_bind and writers_bind module parameters")
Suggested-by: Zhang Changzhong <zhangchangzhong@huawei.com>
Signed-off-by: Wang Liang <wangliang74@huawei.com>
---
 kernel/locking/locktorture.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index ce0362f0a871..6567e5eeacc0 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -103,8 +103,8 @@ static const struct kernel_param_ops lt_bind_ops = {
 	.get = param_get_cpumask,
 };
 
-module_param_cb(bind_readers, &lt_bind_ops, &bind_readers, 0644);
-module_param_cb(bind_writers, &lt_bind_ops, &bind_writers, 0644);
+module_param_cb(bind_readers, &lt_bind_ops, &bind_readers, 0444);
+module_param_cb(bind_writers, &lt_bind_ops, &bind_writers, 0444);
 
 long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool dowarn);
 
@@ -1211,6 +1211,10 @@ static void lock_torture_cleanup(void)
 			cxt.cur_ops->exit();
 		cxt.init_called = false;
 	}
+
+	free_cpumask_var(bind_readers);
+	free_cpumask_var(bind_writers);
+
 	torture_cleanup_end();
 }
 
-- 
2.34.1
Re: [PATCH v2] locktorture: Fix memory leak in param_set_cpumask()
Posted by Paul E. McKenney 3 months, 2 weeks ago
On Fri, Sep 26, 2025 at 11:57:17AM +0800, Wang Liang wrote:
> With CONFIG_CPUMASK_OFFSTACK=y, the 'bind_writers' buffer is allocated via
> alloc_cpumask_var() in param_set_cpumask(). But it is not freed, when
> setting the module parameter multiple times by sysfs interface or removing
> module.
> 
> Below kmemleak trace is seen for this issue:
> 
> unreferenced object 0xffff888100aabff8 (size 8):
>   comm "bash", pid 323, jiffies 4295059233
>   hex dump (first 8 bytes):
>     07 00 00 00 00 00 00 00                          ........
>   backtrace (crc ac50919):
>     __kmalloc_node_noprof+0x2e5/0x420
>     alloc_cpumask_var_node+0x1f/0x30
>     param_set_cpumask+0x26/0xb0 [locktorture]
>     param_attr_store+0x93/0x100
>     module_attr_store+0x1b/0x30
>     kernfs_fop_write_iter+0x114/0x1b0
>     vfs_write+0x300/0x410
>     ksys_write+0x60/0xd0
>     do_syscall_64+0xa4/0x260
>     entry_SYSCALL_64_after_hwframe+0x77/0x7f
> 
> This issue can be reproduced by:
>   insmod locktorture.ko bind_writers=1
>   rmmod locktorture
> 
> or:
>   insmod locktorture.ko bind_writers=1
>   echo 2 > /sys/module/locktorture/parameters/bind_writers
> 
> Considering that setting the module parameter 'bind_writers' or
> 'bind_readers' by sysfs interface has no real effect, set the parameter
> permissions to 0444. To fix the memory leak when removing module, free
> 'bind_writers' and 'bind_readers' memory in lock_torture_cleanup().
> 
> Fixes: 73e341242483 ("locktorture: Add readers_bind and writers_bind module parameters")
> Suggested-by: Zhang Changzhong <zhangchangzhong@huawei.com>
> Signed-off-by: Wang Liang <wangliang74@huawei.com>

I have pulled this in for further review and testing, and please accept
my apologies for the delay.

							Thanx, Paul

> ---
>  kernel/locking/locktorture.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
> index ce0362f0a871..6567e5eeacc0 100644
> --- a/kernel/locking/locktorture.c
> +++ b/kernel/locking/locktorture.c
> @@ -103,8 +103,8 @@ static const struct kernel_param_ops lt_bind_ops = {
>  	.get = param_get_cpumask,
>  };
>  
> -module_param_cb(bind_readers, &lt_bind_ops, &bind_readers, 0644);
> -module_param_cb(bind_writers, &lt_bind_ops, &bind_writers, 0644);
> +module_param_cb(bind_readers, &lt_bind_ops, &bind_readers, 0444);
> +module_param_cb(bind_writers, &lt_bind_ops, &bind_writers, 0444);
>  
>  long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool dowarn);
>  
> @@ -1211,6 +1211,10 @@ static void lock_torture_cleanup(void)
>  			cxt.cur_ops->exit();
>  		cxt.init_called = false;
>  	}
> +
> +	free_cpumask_var(bind_readers);
> +	free_cpumask_var(bind_writers);
> +
>  	torture_cleanup_end();
>  }
>  
> -- 
> 2.34.1
>
Re: [PATCH v2] locktorture: Fix memory leak in param_set_cpumask()
Posted by Wang Liang 3 months, 3 weeks ago
在 2025/9/26 11:57, Wang Liang 写道:
> With CONFIG_CPUMASK_OFFSTACK=y, the 'bind_writers' buffer is allocated via
> alloc_cpumask_var() in param_set_cpumask(). But it is not freed, when
> setting the module parameter multiple times by sysfs interface or removing
> module.
>
> Below kmemleak trace is seen for this issue:
>
> unreferenced object 0xffff888100aabff8 (size 8):
>    comm "bash", pid 323, jiffies 4295059233
>    hex dump (first 8 bytes):
>      07 00 00 00 00 00 00 00                          ........
>    backtrace (crc ac50919):
>      __kmalloc_node_noprof+0x2e5/0x420
>      alloc_cpumask_var_node+0x1f/0x30
>      param_set_cpumask+0x26/0xb0 [locktorture]
>      param_attr_store+0x93/0x100
>      module_attr_store+0x1b/0x30
>      kernfs_fop_write_iter+0x114/0x1b0
>      vfs_write+0x300/0x410
>      ksys_write+0x60/0xd0
>      do_syscall_64+0xa4/0x260
>      entry_SYSCALL_64_after_hwframe+0x77/0x7f
>
> This issue can be reproduced by:
>    insmod locktorture.ko bind_writers=1
>    rmmod locktorture
>
> or:
>    insmod locktorture.ko bind_writers=1
>    echo 2 > /sys/module/locktorture/parameters/bind_writers
>
> Considering that setting the module parameter 'bind_writers' or
> 'bind_readers' by sysfs interface has no real effect, set the parameter
> permissions to 0444. To fix the memory leak when removing module, free
> 'bind_writers' and 'bind_readers' memory in lock_torture_cleanup().
>
> Fixes: 73e341242483 ("locktorture: Add readers_bind and writers_bind module parameters")
> Suggested-by: Zhang Changzhong <zhangchangzhong@huawei.com>
> Signed-off-by: Wang Liang <wangliang74@huawei.com>
> ---
>   kernel/locking/locktorture.c | 8 ++++++--
>   1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
> index ce0362f0a871..6567e5eeacc0 100644
> --- a/kernel/locking/locktorture.c
> +++ b/kernel/locking/locktorture.c
> @@ -103,8 +103,8 @@ static const struct kernel_param_ops lt_bind_ops = {
>   	.get = param_get_cpumask,
>   };
>   
> -module_param_cb(bind_readers, &lt_bind_ops, &bind_readers, 0644);
> -module_param_cb(bind_writers, &lt_bind_ops, &bind_writers, 0644);
> +module_param_cb(bind_readers, &lt_bind_ops, &bind_readers, 0444);
> +module_param_cb(bind_writers, &lt_bind_ops, &bind_writers, 0444);
>   
>   long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool dowarn);
>   
> @@ -1211,6 +1211,10 @@ static void lock_torture_cleanup(void)
>   			cxt.cur_ops->exit();
>   		cxt.init_called = false;
>   	}
> +
> +	free_cpumask_var(bind_readers);
> +	free_cpumask_var(bind_writers);
> +
>   	torture_cleanup_end();
>   }
>   


ping