[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <0171b6cc-95ee-3538-913b-65a391a446b3@huawei.com>
Date: Mon, 29 Jan 2024 19:51:14 +0800
From: Zhihao Cheng <chengzhihao1@...wei.com>
To: Chenyuan Yang <chenyuan0y@...il.com>
CC: <linux-mtd@...ts.infradead.org>, <richard@....at>,
<miquel.raynal@...tlin.com>, <vigneshr@...com>,
<linux-kernel@...r.kernel.org>, <syzkaller@...glegroups.com>, Zijie Zhao
<zzjas98@...il.com>
Subject: Re: [Linux Kernel Bug] memory leak in ubi_attach
在 2024/1/24 22:41, Chenyuan Yang 写道:
> Hi Zhihao,
>
> Thanks very much for your reply and further exploration of this crash!
>
> I have attached the config to reproduce this memory leak. For the
> command line, you can use qemu to boot the kernel (You need to build
> the bullseye-image first).
> ```
> mkdir -p logs
> qemu-system-x86_64 \
> -m 2G \
> -smp 2 \
> -kernel linux/arch/x86/boot/bzImage \
> -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
> -drive file=image/bullseye-qemu.img,format=raw \
> -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
> -net nic,model=e1000 \
> -enable-kvm \
> -nographic \
> -pidfile vm.pid \
> ```
>
> In qemu, you can run
> ```
> gcc -pthread repro.c -o exe
> ./exe
> ```
> to reproduce the memory leak.
>
The bad news is that I can't reproduce the problem with your kernel
config. The good news is that I seem to find the cause of the problem by
code reviewing:
alloc_ai -> kmem_cache_create -> kmem_cache_create_usercopy:
s = __kmem_cache_alias
s = find_mergeable // cannot find mergeable kmem_cache, s = NULL
create_cache
s = kmem_cache_zalloc
__kmem_cache_create(s)
sysfs_slab_add
kobject_init_and_add(&s->kobj)
kobject_init(kobj) // kobj->kref = 1
kobject_add_varg
kobject_set_name_vargs
kvasprintf_const
kstrdup_const
kstrdup
kmalloc_track_caller // allocated memory
kobj->name = s // assign allocated memory to kobj->name
kobject_add_internal
create_dir // failed caused by ENOMEM
// kobj->name won't be released even 's' is released
You can reproduce it by executing ubiattach -m0 with reproduce.diff applied:
[root@...alhost ~]# cat /sys/kernel/debug/kmemleak
unreferenced object 0xffff88813b488080 (size 16):
comm "ubiattach", pid 9535, jiffies 4294943095
hex dump (first 16 bytes):
3a 30 30 30 30 30 35 36 00 00 00 00 00 00 00 00 :0000056........
backtrace (crc 8a117ab9):
[<ffffffff815f91c2>] __kmalloc_node_track_caller+0x322/0x420
[<ffffffff81575efc>] kstrdup+0x3c/0x70
[<ffffffff81575f8f>] kstrdup_const+0x5f/0x70
[<ffffffff82535426>] kvasprintf_const+0xc6/0x110
[<ffffffff84b88cb0>] kobject_set_name_vargs+0x40/0xd0
[<ffffffff84b8911b>] kobject_init_and_add+0x8b/0xf0
[<ffffffff815faba9>] sysfs_slab_add+0x119/0x1e0
[<ffffffff815fc2dc>] __kmem_cache_create+0x41c/0x590
[<ffffffff81586019>] kmem_cache_create_usercopy+0x169/0x300
[<ffffffff815861c1>] kmem_cache_create+0x11/0x20
[<ffffffff82ec8896>] ubi_attach+0xc6/0x1de0
[<ffffffff82eb77a3>] ubi_attach_mtd_dev+0x8a3/0x1120
[<ffffffff82eb8bfc>] ctrl_cdev_ioctl+0x1fc/0x270
[<ffffffff816ca312>] __x64_sys_ioctl+0xf2/0x140
[<ffffffff84bc3970>] do_syscall_64+0x50/0x140
[<ffffffff84c0008b>] entry_SYSCALL_64_after_hwframe+0x63/0x6b
There are two ways to fix it:
1. Release kobj->name directly in the error baranch of
kobject_add_internal() after calling create_dir().
2. Put kobj's refcnt in the error baranch of kobject_add_internal()
after calling create_dir().
I'm not sure which one is better or whether there are other fix methods,
maybe you can send an email in kobj related mailiing lists to confirm
the problem.
View attachment "reproduce.diff" of type "text/plain" (2746 bytes)
Powered by blists - more mailing lists