From: Matt Helsley <matthltc@us.ibm.com>
To: "Serge E. Hallyn" <serge@hallyn.com>
Cc: linux-mm@kvack.org, LKML <linux-kernel@vger.kernel.org>
Subject: Re: [RFC][PATCH] Replacing the /proc/<pid|self>/exe symlink code
Date: Fri, 01 Jun 2007 17:42:49 -0700 [thread overview]
Message-ID: <1180744969.6104.20.camel@localhost.localdomain> (raw)
In-Reply-To: <20070601223156.GA22754@vino.hallyn.com>
On Fri, 2007-06-01 at 17:31 -0500, Serge E. Hallyn wrote:
> Quoting Matt Helsley (matthltc@us.ibm.com):
> > On Wed, 2007-05-30 at 13:09 -0500, Serge E. Hallyn wrote:
> > > Quoting Matt Helsley (matthltc@us.ibm.com):
> > > > This patch avoids holding the mmap semaphore while walking VMAs in response to
> > > > programs which read or follow the /proc/<pid|self>/exe symlink. This also allows us
> > > > to merge mmu and nommu proc_exe_link() functions. The costs are holding a separate
> > > > reference to the executable file stored in the task struct and increased code in
> > > > fork, exec, and exit paths.
> > > >
> > > > Signed-off-by: Matt Helsley <matthltc@us.ibm.com>
> > > > ---
> > > >
> > > > Compiled and passed simple tests for regressions when patched against a 2.6.20
> > > > and 2.6.22-rc2-mm1 kernel.
> > > >
> > > > fs/exec.c | 5 +++--
> > > > fs/proc/base.c | 20 ++++++++++++++++++++
> > > > fs/proc/internal.h | 1 -
> > > > fs/proc/task_mmu.c | 34 ----------------------------------
> > > > fs/proc/task_nommu.c | 34 ----------------------------------
> > > > include/linux/sched.h | 1 +
> > > > kernel/exit.c | 2 ++
> > > > kernel/fork.c | 10 +++++++++-
> > > > 8 files changed, 35 insertions(+), 72 deletions(-)
> >
> > <snip>
> >
> > > > Index: linux-2.6.22-rc2-mm1/kernel/exit.c
> > > > ===================================================================
> > > > --- linux-2.6.22-rc2-mm1.orig/kernel/exit.c
> > > > +++ linux-2.6.22-rc2-mm1/kernel/exit.c
> > > > @@ -924,10 +924,12 @@ fastcall void do_exit(long code)
> > > > if (unlikely(tsk->audit_context))
> > > > audit_free(tsk);
> > > >
> > > > taskstats_exit(tsk, group_dead);
> > > >
> > > > + if (tsk->exe_file)
> > > > + fput(tsk->exe_file);
> > >
> > > Hi,
> > >
> > > just taking a cursory look so I may be missing something, but doesn't
> > > this leave the possibility that right here, with tsk->exe_file being
> > > put, another task would try to look at tsk's /proc/tsk->pid/exe?
> > >
> > > thanks,
> > > -serge
> > >
> > > exit_mm(tsk);
> > >
> >
> > <snip>
> >
> > Good question. To be precise, I think the problem doesn't exist here but
> > after the exit_mm() because there's a VMA that holds a reference to the
> > same file.
> >
> > The existing code appears to solve the race between
> > reading/following /proc/tsk->pid/exe and exit_mm() in the exit path by
> > returning -ENOENT for the case where there is no executable VMA with a
> > reference to the file backing it.
> >
> > So I need to put NULL in the exe_file field and adjust the return value
> > to be -ENOENT instead of -ENOSYS.
> >
> > Thanks for the review!
>
> Ok, I had to think about this a bit, but so you're saying you set it to
> NULL in do_exit(), and anyone who has just dereferenced tsk->exe_file
> before the fput in do_exit() should be ok because the vma hasn't yet
> been put?
Yes
> Should the
> if (!task->exe_file)
> goto out;
> *mnt = mntget(task->exe_file->f_path.mnt);
> *dentry = dget(task->exe_file->f_path.dentry);
>
> also go inside an preempt_disable to prevent sleeping and maybe become
It needs some form of protection from concurrent access between write
and read. write happens during exec, fork, and exit. In the fork case
however it's not necessary because the new task isn't visible in /proc
yet and the value of current doesn't change anyway.
> exef = task->exe_file; /* to prevent task->exe_file being set
> to NULL before we've grabbed the path */
> if (!exef)
> goto out;
> get_file(exef); /* to prevent the mm somehow being put before
> we've grabbed the path? */
> *mnt = mntget(task->exe_file->f_path.mnt);
> *dentry = dget(task->exe_file->f_path.dentry);
> put_file(exef); /* ? */
>
> ?
>
> Or am I being overly paranoid?
No, you're right. In fact, because readlink() can be initiated by
another task I think disabling preemption really only fixes the problem
on uniprocessor systems. So I was thinking of using task_lock() to
protect exe_file.
Cheers,
-Matt Helsley
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2007-06-02 0:39 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-30 0:52 Matt Helsley
2007-05-30 18:09 ` Serge E. Hallyn
2007-05-31 6:01 ` Chris Wright
2007-06-01 1:13 ` Matt Helsley
2007-05-31 17:56 ` Matt Helsley
2007-06-01 22:31 ` Serge E. Hallyn
2007-06-02 0:42 ` Matt Helsley [this message]
2007-06-02 0:46 Matt Helsley
2007-06-06 22:21 ` Serge E. Hallyn
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=1180744969.6104.20.camel@localhost.localdomain \
--to=matthltc@us.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=serge@hallyn.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