Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

locktorture: Fix memory leak in param_set_cpumask()

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>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Frederic Weisbecker <frederic@kernel.org>

authored by

Wang Liang and committed by
Frederic Weisbecker
e52b4388 d1e6d277

+6 -2
+6 -2
kernel/locking/locktorture.c
··· 103 103 .get = param_get_cpumask, 104 104 }; 105 105 106 - module_param_cb(bind_readers, &lt_bind_ops, &bind_readers, 0644); 107 - module_param_cb(bind_writers, &lt_bind_ops, &bind_writers, 0644); 106 + module_param_cb(bind_readers, &lt_bind_ops, &bind_readers, 0444); 107 + module_param_cb(bind_writers, &lt_bind_ops, &bind_writers, 0444); 108 108 109 109 long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool dowarn); 110 110 ··· 1211 1211 cxt.cur_ops->exit(); 1212 1212 cxt.init_called = false; 1213 1213 } 1214 + 1215 + free_cpumask_var(bind_readers); 1216 + free_cpumask_var(bind_writers); 1217 + 1214 1218 torture_cleanup_end(); 1215 1219 } 1216 1220