mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Neil Horman <nhorman@tuxdriver.com>
To: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Andi Kleen <andi@firstfloor.org>,
	Jiri Slaby <jirislaby@gmail.com>,
	linux-kernel@vger.kernel.org, Greg KH <gregkh@suse.de>,
	Kay Sievers <kay.sievers@suse.de>
Subject: Re: oops in uevent_helper [was: mmotm 2010-01-13-12-17 uploaded]
Date: Mon, 15 Feb 2010 16:42:52 -0500	[thread overview]
Message-ID: <20100215214252.GA7828@hmsreliant.think-freely.org> (raw)
In-Reply-To: <20100215201233.GI6750@linux.vnet.ibm.com>

On Mon, Feb 15, 2010 at 12:12:33PM -0800, Paul E. McKenney wrote:
> On Fri, Feb 12, 2010 at 12:06:24PM -0500, Neil Horman wrote:
> > On Thu, Feb 11, 2010 at 09:27:08PM -0800, Andrew Morton wrote:
> > > On Fri, 12 Feb 2010 06:21:26 +0100 Andi Kleen <andi@firstfloor.org> wrote:
> > > 
> > > > > urgh, must I?  That trashes Neil's
> > > > > kmod-add-init-function-to-usermodehelper.patch and
> > > > > kmod-replace-call_usermodehelper_pipe-with-use-of-umh-init-function-and-resolve-limit.patch
> > > > > and probably requires repairing other stuff and sets the testing status
> > > > > back to "square one".
> > > > > 
> > > > > If you have patches queued, please make the time to support them!
> > > > 
> > > > Ok, understood. I'll try to look into it today.
> > > 
> > > Ta.  As I mentioned to Neil, if it looks serious then let's shelve it
> > > all and revisit for 2.6.35.
> > > 
> > > > You want incrementals?
> > > 
> > > If convenient, please.  Otherwise we can drop--and-remerge.
> > > 
> > > 
> > 
> > 
> > Ok, this fixes the oops Jiri reported for me.  Its been tested by me, but only
> > minimally, and my rcu-foo is not the greatest, so through reviews appreciated.
> > The patch is incremental against the latest mmotm as of this AM.
> 
> A few questions interspersed below...
> 
> 							Thanx, Paul
> 
> > Thanks!
> > Neil
> > 
> > 
> > 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@tuxdriver.com>
> > 
> > 
> >  kernel/ksysfs.c      |   38 ++++++++++++++++++++++++++++++++++++--
> >  lib/kobject_uevent.c |    4 +++-
> >  2 files changed, 39 insertions(+), 3 deletions(-)
> > 
> > diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
> > index 21fe3c4..66d1e5b 100644
> > --- a/kernel/ksysfs.c
> > +++ b/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;
> 
> Given that you kfree() something that might be equal to dfl, I am
> hoping that the CONFIG_UEVENT_HELPER_PATH macro expands to something
> that kfree() can do something with...
> 
> Or did you mean to put a "return;" in the then-clause of the "if"
> statement below?
> 
No, I meant what I have.  CONFIG_UEVENT_HELPER_PATH expands to a string.  if the
old pointer is not NULL, and doesn't point to the default string (we don't want
to free something in the string table), then we kfree it, since it must have
been allocated in uevent_helper_store

> > +	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);
> 
> Some lock protects this?  Or does something else prevent multiple
> instances of uevent_helper_store() from executing concurrently?
> 
I had thought that there was a per-file sysfs lock that protected this, but I
wasn't sure.  Regardless, I would have thought this was safe, since
rcu_assign_pointer was serialized by rcu quiescence. Am I mistaken?

> > +	call_rcu(&old->rcu, free_old_uevent_ptr);
> > +
> >  	return count;
> > +
> > +out_free:
> > +	kfree(kbuf);
> > +	return -ENOMEM;
> >  }
> >  KERNEL_ATTR_RW(uevent_helper);
> >  #endif
> > diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
> > index c2383f3..211f846 100644
> > --- a/lib/kobject_uevent.c
> > +++ b/lib/kobject_uevent.c
> > @@ -126,6 +126,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
> >  	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 *kobj, enum kobject_action action,
> >  #endif
> > 
> >  	/* call uevent_helper, usually only enabled during early boot */
> > -	if (uevent_helper[0])
> > +	helper = rcu_dereference(uevent_helper);
> 
> This is protected by a pre-existing rcu_read_lock() somewhere?
> 
Does rcu_dereference not start a quiescence point the same way rcu_read_lock
does? AS I said, rcu isn't my strong suit :)

Neil

> If not, an rcu_read_lock() / rcu_read_unlock() pair is needed that
> covers both the rcu_dereference() and any subsequent dereferences of the
> pointer returned by rcu_dereference().
> 
> > +	if (helper[0])
> >  		retval = uevent_call_helper(subsystem, env);
> > 
> >  exit:
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/
> 

  reply	other threads:[~2010-02-15 21:43 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-13 20:17 mmotm 2010-01-13-12-17 uploaded akpm
2010-01-13 22:16 ` mmotm 2010-01-13-12-17 - 'make oldconfig' dies Valdis.Kletnieks
2010-01-14 16:07 ` mmotm 2010-01-13-12-17 uploaded (cgroup) Randy Dunlap
2010-01-14 17:20   ` Ben Blum
2010-01-18  2:03     ` Randy Dunlap
2010-01-14 16:18 ` [PATCH -mmotm] tty.h: make function static Randy Dunlap
2010-01-15 19:33 ` mmotm 2010-01-13-12-17 uploaded Jiri Slaby
2010-01-15 23:38   ` oops in uevent_helper [was: mmotm 2010-01-13-12-17 uploaded] Jiri Slaby
2010-01-22 23:52     ` Andrew Morton
2010-02-10 19:54       ` Jiri Slaby
2010-02-11 20:57         ` Andi Kleen
2010-02-11 22:25           ` Andrew Morton
2010-02-12  2:39             ` Neil Horman
2010-02-12  3:10               ` Andrew Morton
2010-02-12  5:21             ` Andi Kleen
2010-02-12  5:27               ` Andrew Morton
2010-02-12 17:06                 ` Neil Horman
2010-02-14 17:32                   ` Jiri Slaby
2010-02-14 17:54                     ` Neil Horman
2010-02-15 20:12                   ` Paul E. McKenney
2010-02-15 21:42                     ` Neil Horman [this message]
2010-02-15 22:16                       ` Paul E. McKenney
2010-02-16  1:37                         ` Neil Horman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100215214252.GA7828@hmsreliant.think-freely.org \
    --to=nhorman@tuxdriver.com \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=gregkh@suse.de \
    --cc=jirislaby@gmail.com \
    --cc=kay.sievers@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulmck@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®