The patch titled sysctl: fix up remaining references to uevent_helper() has been added to the -mm tree. Its filename is sysctl-fix-up-remaining-references-to-uevent_helper.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** See http://userweb.kernel.org/~akpm/stuff/added-to-mm.txt to find out what to do about this The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/ ------------------------------------------------------ Subject: sysctl: fix up remaining references to uevent_helper() From: Neil Horman <nhorman@xxxxxxxxxxxxx> Fix up remaining references to uevent_helper to play nice with Andi's uevent_helper/rcu changes. Some changes were made recently which modified uevent_helper to be an rcu protected pointer, rather than a static char array. This has led to a few missed points in which the sysfs path still assumed that: 1) the uevent_helper symbol could still be accessed safely without rcu_dereference 2) that the sysfs path could copy data to that pointer safely. I've fixed this by chaging the sysfs path so that it duplicates the string on uevent_helper_store, and freeing it (only if it doesn't point to the CONFIG_DEFAULT_UEVENT_HELPER string), in a call_rcu post-quiescent point. I've also fixed up the remaining references to the uevent_helper pointers to use rcu_dereference. Signed-off-by: Neil Horman <nhorman@xxxxxxxxxxxxx> Cc: Andi Kleen <andi@xxxxxxxxxxxxxx> Cc: Jiri Slaby <jirislaby@xxxxxxxxx> Cc: Greg KH <gregkh@xxxxxxx> Cc: Kay Sievers <kay.sievers@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- kernel/ksysfs.c | 38 ++++++++++++++++++++++++++++++++++++-- lib/kobject_uevent.c | 4 +++- 2 files changed, 39 insertions(+), 3 deletions(-) diff -puN kernel/ksysfs.c~sysctl-fix-up-remaining-references-to-uevent_helper kernel/ksysfs.c --- a/kernel/ksysfs.c~sysctl-fix-up-remaining-references-to-uevent_helper +++ a/kernel/ksysfs.c @@ -37,19 +37,53 @@ KERNEL_ATTR_RO(uevent_seqnum); static ssize_t uevent_helper_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%s\n", uevent_helper); + return sprintf(buf, "%s\n", rcu_dereference(uevent_helper)); } + +struct uevent_helper_rcu { + char *oldptr; + struct rcu_head rcu; +}; + +static void free_old_uevent_ptr(struct rcu_head *list) +{ + struct uevent_helper_rcu *ptr; + char *dfl = CONFIG_UEVENT_HELPER_PATH; + ptr = container_of(list, struct uevent_helper_rcu, rcu); + if (ptr->oldptr && (ptr->oldptr != dfl)) + kfree(ptr->oldptr); + + kfree(ptr); +} + static ssize_t uevent_helper_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { + char *kbuf; + struct uevent_helper_rcu *old; + if (count+1 > UEVENT_HELPER_PATH_LEN) return -ENOENT; - memcpy(uevent_helper, buf, count); + kbuf = kstrndup(buf, UEVENT_HELPER_PATH_LEN, GFP_KERNEL); + if (!kbuf) + return -ENOMEM; uevent_helper[count] = '\0'; if (count && uevent_helper[count-1] == '\n') uevent_helper[count-1] = '\0'; + old = kmalloc(sizeof(struct uevent_helper_rcu), GFP_KERNEL); + if (!old) + goto out_free; + + old->oldptr = rcu_dereference(uevent_helper); + rcu_assign_pointer(uevent_helper, kbuf); + call_rcu(&old->rcu, free_old_uevent_ptr); + return count; + +out_free: + kfree(kbuf); + return -ENOMEM; } KERNEL_ATTR_RW(uevent_helper); #endif diff -puN lib/kobject_uevent.c~sysctl-fix-up-remaining-references-to-uevent_helper lib/kobject_uevent.c --- a/lib/kobject_uevent.c~sysctl-fix-up-remaining-references-to-uevent_helper +++ a/lib/kobject_uevent.c @@ -126,6 +126,7 @@ int kobject_uevent_env(struct kobject *k struct kset *kset; const struct kset_uevent_ops *uevent_ops; u64 seq; + const char *helper; int i = 0; int retval = 0; @@ -272,7 +273,8 @@ int kobject_uevent_env(struct kobject *k #endif /* call uevent_helper, usually only enabled during early boot */ - if (uevent_helper[0]) + helper = rcu_dereference(uevent_helper); + if (helper[0]) retval = uevent_call_helper(subsystem, env); exit: _ Patches currently in -mm which might be from nhorman@xxxxxxxxxxxxx are origin.patch linux-next.patch coredump-set-group_exit_code-for-other-clone_vm-tasks-too.patch sysctl-fix-up-remaining-references-to-uevent_helper.patch kmod-add-init-function-to-usermodehelper.patch kmod-add-init-function-to-usermodehelper-fix.patch kmod-replace-call_usermodehelper_pipe-with-use-of-umh-init-function-and-resolve-limit.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html