[PATCH] driver core: Cancel the attach if device addition fails

Edward Adam Davis posted 1 patch 1 month, 2 weeks ago
drivers/base/dd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] driver core: Cancel the attach if device addition fails
Posted by Edward Adam Davis 1 month, 2 weeks ago
syzbot reported a null-ptr-deref below [1] following a fault injection in
device_add(). [0]

When device_add() fails, dev->p is NULL.
Later, __device_attach() tries to access members of
dev->p(e.g., dev->p->dead), the issue in [1] is triggered.

Let's handle the error of __device_attach() properly.

[0]
FAULT_INJECTION: forcing a failure.
name failslab, interval 1, probability 1, space 0, times 1000000
Workqueue: events_long serio_handle_event
Call Trace:
 kmem_cache_alloc_noprof+0x91/0x6a0
 kernfs_new_node+0x117/0x150
 __kernfs_create_file+0x53/0x350
 sysfs_add_file_mode_ns+0x207/0x3c0
 internal_create_group+0x593/0xfb0
 internal_create_groups+0x9d/0x150
 device_add+0xf60/0x1970
 serio_handle_event+0x59b/0x990

[1]
KASAN: null-ptr-deref in range [0x0000000000000108-0x000000000000010f]
RIP: 0010:__device_attach+0xb0/0x4d0 drivers/base/dd.c:1074
Call Trace:
 serio_find_driver drivers/input/serio/serio.c:112 [inline]
 serio_handle_event+0x60a/0x990 drivers/input/serio/serio.c:206

Fixes: 654888327e9f ("driver core: Avoid binding drivers to dead devices")
Reported-by: syzbot+de42beb9ccc760a210ab@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=de42beb9ccc760a210ab
Tested-by: syzbot+de42beb9ccc760a210ab@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
---
 drivers/base/dd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 60c005223844..d345f6c175a6 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -1071,7 +1071,7 @@ static int __device_attach(struct device *dev, bool allow_async)
 	bool async = false;
 
 	device_lock(dev);
-	if (dev->p->dead) {
+	if (!dev->p || dev->p->dead) {
 		goto out_unlock;
 	} else if (dev->driver) {
 		if (device_is_bound(dev)) {
-- 
2.43.0