From: Aristeu Rozanski <aris@redhat.com>
To: "Herton R. Krzesinski" <herton@redhat.com>
Cc: linux-kernel@vger.kernel.org,
Andrew Morton <akpm@linux-foundation.org>,
Davidlohr Bueso <dave@stgolabs.net>,
Manfred Spraul <manfred@colorfullife.com>,
Rafael Aquini <aquini@redhat.com>, Joe Perches <joe@perches.com>,
djeffery@redhat.com
Subject: Re: [PATCH] ipc,sem: fix use after free on IPC_RMID after a task using same semaphore set exits
Date: Fri, 7 Aug 2015 15:30:55 -0400 [thread overview]
Message-ID: <20150807193055.GD23305@redhat.com> (raw)
In-Reply-To: <1438967375-14877-1-git-send-email-herton@redhat.com>
On Fri, Aug 07, 2015 at 02:09:35PM -0300, Herton R. Krzesinski wrote:
> The current semaphore code allows a potential use after free: in exit_sem we may
> free the task's sem_undo_list while there is still another task looping through
> the same semaphore set and cleaning the sem_undo list at freeary function (the
> task called IPC_RMID for the same semaphore set).
>
> For example, with a test program [1] running which keeps forking a lot of processes
> (which then do a semop call with SEM_UNDO flag), and with the parent right after
> removing the semaphore set with IPC_RMID, and a kernel built with CONFIG_SLAB,
> CONFIG_SLAB_DEBUG and CONFIG_DEBUG_SPINLOCK, you can easily see something like
> the following in the kernel log:
(snip)
> Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
> ---
> ipc/sem.c | 24 ++++++++++++++++--------
> 1 file changed, 16 insertions(+), 8 deletions(-)
>
> diff --git a/ipc/sem.c b/ipc/sem.c
> index bc3d530..35ccddd 100644
> --- a/ipc/sem.c
> +++ b/ipc/sem.c
> @@ -2074,17 +2074,24 @@ void exit_sem(struct task_struct *tsk)
> rcu_read_lock();
> un = list_entry_rcu(ulp->list_proc.next,
> struct sem_undo, list_proc);
> - if (&un->list_proc == &ulp->list_proc)
> - semid = -1;
> - else
> - semid = un->semid;
> + if (&un->list_proc == &ulp->list_proc) {
> + rcu_read_unlock();
> + /* Make sure we wait for any place still referencing
> + * the current ulp to finish */
> + synchronize_rcu();
> + break;
> + }
> + spin_lock(&ulp->lock);
> + semid = un->semid;
> + spin_unlock(&ulp->lock);
>
> + /* exit_sem raced with IPC_RMID, nothing to do */
> if (semid == -1) {
> rcu_read_unlock();
> - break;
> + continue;
> }
>
> - sma = sem_obtain_object_check(tsk->nsproxy->ipc_ns, un->semid);
> + sma = sem_obtain_object_check(tsk->nsproxy->ipc_ns, semid);
> /* exit_sem raced with IPC_RMID, nothing to do */
> if (IS_ERR(sma)) {
> rcu_read_unlock();
> @@ -2112,9 +2119,10 @@ void exit_sem(struct task_struct *tsk)
> ipc_assert_locked_object(&sma->sem_perm);
> list_del(&un->list_id);
>
> - spin_lock(&ulp->lock);
> + /* we should be the last process using this ulp, so no need
> + * to acquire ulp->lock here; we are also protected against
> + * IPC_RMID as we hold sma->sem_perm.lock */
> list_del_rcu(&un->list_proc);
> - spin_unlock(&ulp->lock);
>
> /* perform adjustments registered in un */
> for (i = 0; i < sma->sem_nsems; i++) {
I was debugging the same issue and can confirm this fix works and makes
sense.
Acked-by: Aristeu Rozanski <aris@redhat.com>
--
Aristeu
next prev parent reply other threads:[~2015-08-07 19:31 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-07 17:09 [PATCH] ipc,sem: fix use after free on IPC_RMID after a task using same semaphore set exits Herton R. Krzesinski
2015-08-07 19:30 ` Aristeu Rozanski [this message]
2015-08-09 17:49 ` Manfred Spraul
2015-08-10 15:31 ` Herton R. Krzesinski
2015-08-10 19:02 ` Manfred Spraul
2015-08-11 16:48 ` Herton R. Krzesinski
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=20150807193055.GD23305@redhat.com \
--to=aris@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=aquini@redhat.com \
--cc=dave@stgolabs.net \
--cc=djeffery@redhat.com \
--cc=herton@redhat.com \
--cc=joe@perches.com \
--cc=linux-kernel@vger.kernel.org \
--cc=manfred@colorfullife.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.