Patch "watchdog: Fix kmemleak in watchdog_cdev_register" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    watchdog: Fix kmemleak in watchdog_cdev_register

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     watchdog-fix-kmemleak-in-watchdog_cdev_register.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 1fa8f3f1e88ffbb843d8a26995ae9a5f1ae31179
Author: Chen Jun <chenjun102@xxxxxxxxxx>
Date:   Wed Nov 16 01:27:14 2022 +0000

    watchdog: Fix kmemleak in watchdog_cdev_register
    
    [ Upstream commit 13721a2ac66b246f5802ba1b75ad8637e53eeecc ]
    
    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: 72139dfa2464 ("watchdog: Fix the race between the release of watchdog_core_data and cdev")
    Signed-off-by: Chen Jun <chenjun102@xxxxxxxxxx>
    Reviewed-by: Guenter Roeck <linux@xxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20221116012714.102066-1-chenjun102@xxxxxxxxxx
    Signed-off-by: Guenter Roeck <linux@xxxxxxxxxxxx>
    Signed-off-by: Wim Van Sebroeck <wim@xxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index 8494846ccdc5f..c670d13ab3d98 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -1016,8 +1016,8 @@ static int watchdog_cdev_register(struct watchdog_device *wdd)
 		if (wdd->id == 0) {
 			misc_deregister(&watchdog_miscdev);
 			old_wd_data = NULL;
-			put_device(&wd_data->dev);
 		}
+		put_device(&wd_data->dev);
 		return err;
 	}
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux