summaryrefslogtreecommitdiff
path: root/lib/kobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kobject.c')
-rw-r--r--lib/kobject.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/lib/kobject.c b/lib/kobject.c
index 3e3a5c3cb330..7cbccd2b4c72 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -257,18 +257,32 @@ static int kobject_add_internal(struct kobject *kobj)
int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
va_list vargs)
{
- char *s;
+ const char *s;
if (kobj->name && !fmt)
return 0;
- s = kvasprintf(GFP_KERNEL, fmt, vargs);
+ s = kvasprintf_const(GFP_KERNEL, fmt, vargs);
if (!s)
return -ENOMEM;
- /* ewww... some of these buggers have '/' in the name ... */
- strreplace(s, '/', '!');
- kfree(kobj->name);
+ /*
+ * ewww... some of these buggers have '/' in the name ... If
+ * that's the case, we need to make sure we have an actual
+ * allocated copy to modify, since kvasprintf_const may have
+ * returned something from .rodata.
+ */
+ if (strchr(s, '/')) {
+ char *t;
+
+ t = kstrdup(s, GFP_KERNEL);
+ kfree_const(s);
+ if (!t)
+ return -ENOMEM;
+ strreplace(t, '/', '!');
+ s = t;
+ }
+ kfree_const(kobj->name);
kobj->name = s;
return 0;
@@ -466,7 +480,7 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
envp[0] = devpath_string;
envp[1] = NULL;
- name = dup_name = kstrdup(new_name, GFP_KERNEL);
+ name = dup_name = kstrdup_const(new_name, GFP_KERNEL);
if (!name) {
error = -ENOMEM;
goto out;
@@ -486,7 +500,7 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
kobject_uevent_env(kobj, KOBJ_MOVE, envp);
out:
- kfree(dup_name);
+ kfree_const(dup_name);
kfree(devpath_string);
kfree(devpath);
kobject_put(kobj);
@@ -568,6 +582,7 @@ void kobject_del(struct kobject *kobj)
kobject_put(kobj->parent);
kobj->parent = NULL;
}
+EXPORT_SYMBOL(kobject_del);
/**
* kobject_get - increment refcount for object.
@@ -584,6 +599,7 @@ struct kobject *kobject_get(struct kobject *kobj)
}
return kobj;
}
+EXPORT_SYMBOL(kobject_get);
static struct kobject * __must_check kobject_get_unless_zero(struct kobject *kobj)
{
@@ -632,7 +648,7 @@ static void kobject_cleanup(struct kobject *kobj)
/* free name if we allocated it */
if (name) {
pr_debug("kobject: '%s': free name\n", name);
- kfree(name);
+ kfree_const(name);
}
}
@@ -675,6 +691,7 @@ void kobject_put(struct kobject *kobj)
kref_put(&kobj->kref, kobject_release);
}
}
+EXPORT_SYMBOL(kobject_put);
static void dynamic_kobj_release(struct kobject *kobj)
{
@@ -803,6 +820,7 @@ int kset_register(struct kset *k)
kobject_uevent(&k->kobj, KOBJ_ADD);
return 0;
}
+EXPORT_SYMBOL(kset_register);
/**
* kset_unregister - remove a kset.
@@ -815,6 +833,7 @@ void kset_unregister(struct kset *k)
kobject_del(&k->kobj);
kobject_put(&k->kobj);
}
+EXPORT_SYMBOL(kset_unregister);
/**
* kset_find_obj - search for object in kset.
@@ -1051,10 +1070,3 @@ void kobj_ns_drop(enum kobj_ns_type type, void *ns)
kobj_ns_ops_tbl[type]->drop_ns(ns);
spin_unlock(&kobj_ns_type_lock);
}
-
-EXPORT_SYMBOL(kobject_get);
-EXPORT_SYMBOL(kobject_put);
-EXPORT_SYMBOL(kobject_del);
-
-EXPORT_SYMBOL(kset_register);
-EXPORT_SYMBOL(kset_unregister);