[<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
 
