• Chen Jun's avatar
    watchdog: Fix kmemleak in watchdog_cdev_register · 13721a2a
    Chen Jun authored
    kmemleak reports memory leaks in watchdog_dev_register, as follows:
    unreferenced object 0xffff888116233000 (size 2048):
      comm ""modprobe"", pid 28147, jiffies 4353426116 (age 61.741s)
      hex dump (first 32 bytes):
        80 fa b9 05 81 88 ff ff 08 30 23 16 81 88 ff ff  .........0#.....
        08 30 23 16 81 88 ff ff 00 00 00 00 00 00 00 00  .0#.............
      backtrace:
        [<000000007f001ffd>] __kmem_cache_alloc_node+0x157/0x220
        [<000000006a389304>] kmalloc_trace+0x21/0x110
        [<000000008d640eea>] watchdog_dev_register+0x4e/0x780 [watchdog]
        [<0000000053c9f248>] __watchdog_register_device+0x4f0/0x680 [watchdog]
        [<00000000b2979824>] watchdog_register_device+0xd2/0x110 [watchdog]
        [<000000001f730178>] 0xffffffffc10880ae
        [<000000007a1a8bcc>] do_one_initcall+0xcb/0x4d0
        [<00000000b98be325>] do_init_module+0x1ca/0x5f0
        [<0000000046d08e7c>] load_module+0x6133/0x70f0
        ...
    
    unreferenced object 0xffff888105b9fa80 (size 16):
      comm ""modprobe"", pid 28147, jiffies 4353426116 (age 61.741s)
      hex dump (first 16 bytes):
        77 61 74 63 68 64 6f 67 31 00 b9 05 81 88 ff ff  watchdog1.......
      backtrace:
        [<000000007f001ffd>] __kmem_cache_alloc_node+0x157/0x220
        [<00000000486ab89b>] __kmalloc_node_track_caller+0x44/0x1b0
        [<000000005a39aab0>] kvasprintf+0xb5/0x140
        [<0000000024806f85>] kvasprintf_const+0x55/0x180
        [<000000009276cb7f>] kobject_set_name_vargs+0x56/0x150
        [<00000000a92e820b>] dev_set_name+0xab/0xe0
        [<00000000cec812c6>] watchdog_dev_register+0x285/0x780 [watchdog]
        [<0000000053c9f248>] __watchdog_register_device+0x4f0/0x680 [watchdog]
        [<00000000b2979824>] watchdog_register_device+0xd2/0x110 [watchdog]
        [<000000001f730178>] 0xffffffffc10880ae
        [<000000007a1a8bcc>] do_one_initcall+0xcb/0x4d0
        [<00000000b98be325>] do_init_module+0x1ca/0x5f0
        [<0000000046d08e7c>] load_module+0x6133/0x70f0
        ...
    
    The reason is that put_device is not be called if cdev_device_add fails
    and wdd->id != 0.
    
    watchdog_cdev_register
      wd_data = kzalloc                             [1]
      err = dev_set_name                            [2]
      ..
      err = cdev_device_add
      if (err) {
        if (wdd->id == 0) {  // wdd->id != 0
          ..
        }
        return err;  // [1],[2] would be leaked
    
    To fix it, call put_device in all wdd->id cases.
    
    Fixes: 72139dfa ("watchdog: Fix the race between the release of watchdog_core_data and cdev")
    Signed-off-by: default avatarChen Jun <chenjun102@huawei.com>
    Reviewed-by: default avatarGuenter Roeck <linux@roeck-us.net>
    Link: https://lore.kernel.org/r/20221116012714.102066-1-chenjun102@huawei.comSigned-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
    Signed-off-by: default avatarWim Van Sebroeck <wim@linux-watchdog.org>
    13721a2a
watchdog_dev.c 32.8 KB