Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pps: fix warning in pps_register_cdev when register device fail

Similar to previous commit 2a934fdb01db ("media: v4l2-dev: fix error
handling in __video_register_device()"), the release hook should be set
before device_register(). Otherwise, when device_register() return error
and put_device() try to callback the release function, the below warning
may happen.

------------[ cut here ]------------
WARNING: CPU: 1 PID: 4760 at drivers/base/core.c:2567 device_release+0x1bd/0x240 drivers/base/core.c:2567
Modules linked in:
CPU: 1 UID: 0 PID: 4760 Comm: syz.4.914 Not tainted 6.17.0-rc3+ #1 NONE
RIP: 0010:device_release+0x1bd/0x240 drivers/base/core.c:2567
Call Trace:
<TASK>
kobject_cleanup+0x136/0x410 lib/kobject.c:689
kobject_release lib/kobject.c:720 [inline]
kref_put include/linux/kref.h:65 [inline]
kobject_put+0xe9/0x130 lib/kobject.c:737
put_device+0x24/0x30 drivers/base/core.c:3797
pps_register_cdev+0x2da/0x370 drivers/pps/pps.c:402
pps_register_source+0x2f6/0x480 drivers/pps/kapi.c:108
pps_tty_open+0x190/0x310 drivers/pps/clients/pps-ldisc.c:57
tty_ldisc_open+0xa7/0x120 drivers/tty/tty_ldisc.c:432
tty_set_ldisc+0x333/0x780 drivers/tty/tty_ldisc.c:563
tiocsetd drivers/tty/tty_io.c:2429 [inline]
tty_ioctl+0x5d1/0x1700 drivers/tty/tty_io.c:2728
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:598 [inline]
__se_sys_ioctl fs/ioctl.c:584 [inline]
__x64_sys_ioctl+0x194/0x210 fs/ioctl.c:584
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x5f/0x2a0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x76/0x7e
</TASK>

Before commit c79a39dc8d06 ("pps: Fix a use-after-free"),
pps_register_cdev() call device_create() to create pps->dev, which will
init dev->release to device_create_release(). Now the comment is outdated,
just remove it.

Thanks for the reminder from Calvin Owens, 'kfree_pps' should be removed
in pps_register_source() to avoid a double free in the failure case.

Link: https://lore.kernel.org/all/20250827065010.3208525-1-wangliang74@huawei.com/
Fixes: c79a39dc8d06 ("pps: Fix a use-after-free")
Signed-off-by: Wang Liang <wangliang74@huawei.com>
Reviewed-By: Calvin Owens <calvin@wbinvd.org>
Link: https://lore.kernel.org/r/20250830075023.3498174-1-wangliang74@huawei.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Wang Liang and committed by
Greg Kroah-Hartman
b0531cdb 656a48c4

+3 -7
+1 -4
drivers/pps/kapi.c
··· 109 109 if (err < 0) { 110 110 pr_err("%s: unable to create char device\n", 111 111 info->name); 112 - goto kfree_pps; 112 + goto pps_register_source_exit; 113 113 } 114 114 115 115 dev_dbg(&pps->dev, "new PPS source %s\n", info->name); 116 116 117 117 return pps; 118 - 119 - kfree_pps: 120 - kfree(pps); 121 118 122 119 pps_register_source_exit: 123 120 pr_err("%s: unable to register source\n", info->name);
+2 -3
drivers/pps/pps.c
··· 374 374 pps->info.name); 375 375 err = -EBUSY; 376 376 } 377 + kfree(pps); 377 378 goto out_unlock; 378 379 } 379 380 pps->id = err; ··· 384 383 pps->dev.devt = MKDEV(pps_major, pps->id); 385 384 dev_set_drvdata(&pps->dev, pps); 386 385 dev_set_name(&pps->dev, "pps%d", pps->id); 386 + pps->dev.release = pps_device_destruct; 387 387 err = device_register(&pps->dev); 388 388 if (err) 389 389 goto free_idr; 390 - 391 - /* Override the release function with our own */ 392 - pps->dev.release = pps_device_destruct; 393 390 394 391 pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, pps_major, 395 392 pps->id);