[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1586102749-3364-1-git-send-email-zhangfeionline@gmail.com>
Date: Sun, 5 Apr 2020 09:05:49 -0700
From: zhangfeionline@...il.com
To: gregkh@...uxfoundation.org
Cc: rafael@...nel.org, linux-kernel@...r.kernel.org,
songmuchun@...edance.com, PengfeiZhang <zhangfeionline@...il.com>
Subject: [PATCH] driver core: Fix possible use after free on name
From: PengfeiZhang <zhangfeionline@...il.com>
__class_create() copies the pointer to the name passed as an
argument only to be used later. But there's a chance the caller
could immediately free the passed string(e.g., local variable).
This could trigger a use after free when we use class name(e.g.,
dev_uevent_name()called by device_destroy(),class_create_release()).
To be on the safe side: duplicate the string with kstrdup_const()
so that if an unaware user passes an address to a stack-allocated
buffer, we won't get the arbitrary name and crash.
Signed-off-by: PengfeiZhang <zhangfeionline@...il.com>
---
drivers/base/class.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/base/class.c b/drivers/base/class.c
index bcd410e..770b3b3 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -206,6 +206,7 @@ void class_unregister(struct class *cls)
static void class_create_release(struct class *cls)
{
pr_debug("%s called for %s\n", __func__, cls->name);
+ kfree_const(cls->name);
kfree(cls);
}
@@ -227,7 +228,10 @@ struct class *__class_create(struct module *owner, const char *name,
struct lock_class_key *key)
{
struct class *cls;
- int retval;
+ int retval = -EINVAL;
+
+ if (!name)
+ goto done;
cls = kzalloc(sizeof(*cls), GFP_KERNEL);
if (!cls) {
@@ -235,18 +239,27 @@ struct class *__class_create(struct module *owner, const char *name,
goto error;
}
+ name = kstrdup_const(name, GFP_KERNEL);
+ if (!name) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
cls->name = name;
cls->owner = owner;
cls->class_release = class_create_release;
retval = __class_register(cls, key);
if (retval)
- goto error;
+ goto error_class_register;
return cls;
+error_class_register:
+ kfree(cls->name);
error:
kfree(cls);
+done:
return ERR_PTR(retval);
}
EXPORT_SYMBOL_GPL(__class_create);
--
2.7.4
Powered by blists - more mailing lists