diff options
Diffstat (limited to 'lib/kobject.c')
-rw-r--r-- | lib/kobject.c | 42 |
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); |