Re: [Linux Kernel Bug] memory leak in ubi_attach

From: Ryder Wang
Date: Mon Oct 14 2024 - 23:41:39 EST


By walking through all the related code, it looks to be a bug in slub.c rather than kobject or ubifs.

sysfs_slab_add() calls kobject_init_and_add():
- If kobject_init_and_add fails, sysfs_slab_add() will go to *out*. But unluckily, *out* code block will never release s->kobj, but it is expected to do so.

Below is the function comment of kobject_init_and_add():
* If this function returns an error, kobject_put() must be called to properly clean up the memory associated with the object. *
==> It means sysfs_slab_add() shall release the related kobject.

________________________________________
From: linux-mtd <linux-mtd-bounces@xxxxxxxxxxxxxxxxxxx> on behalf of Chenyuan Yang <chenyuan0y@xxxxxxxxx>
Sent: Friday, October 11, 2024 09:23
To: linux-mtd@xxxxxxxxxxxxxxxxxxx
Cc: richard@xxxxxx; miquel.raynal@xxxxxxxxxxx; Zhihao Cheng; vigneshr@xxxxxx; linux-kernel@xxxxxxxxxxxxxxx; syzkaller@xxxxxxxxxxxxxxxx; Zijie Zhao; gregkh@xxxxxxxxxxxxxxxxxxx; rafael@xxxxxxxxxx; akpm@xxxxxxxxxxxxxxxxxxxx
Subject: Re: [Linux Kernel Bug] memory leak in ubi_attach

Dear Linux Kernel Developers for UBI and Kernel Object,

I am writing to inquire if there have been any updates regarding this
memory leak issue. This issue remains reproducible on the latest
Linux version (6.12-rc2, commit
8cf0b93919e13d1e8d4466eb4080a4c4d9d66d7b).

Thank you for your attention to this matter.

Best,
Chenyuan

On Mon, Jan 29, 2024 at 5:51 AM 'Zhihao Cheng' via syzkaller
<syzkaller@xxxxxxxxxxxxxxxx> wrote:
>
> 在 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@localhost ~]# 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.
>
> --
> You received this message because you are subscribed to the Google Groups "syzkaller" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to syzkaller+unsubscribe@xxxxxxxxxxxxxxxx.
> To view this discussion on the web visit https://groups.google.com/d/msgid/syzkaller/0171b6cc-95ee-3538-913b-65a391a446b3%40huawei.com.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/