From: Manfred Spraul <manfred@colorfullife.com>
To: Rik van Riel <riel@redhat.com>, linux-kernel@vger.kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>,
Davidlohr Bueso <davidlohr@hp.com>,
Rafael Aquini <aquini@redhat.com>,
1vier1@web.de
Subject: Re: [PATCH] ipc,sem block sem_lock on sma->lock during sma initialization
Date: Sun, 23 Nov 2014 19:23:53 +0100 [thread overview]
Message-ID: <54722639.1040605@colorfullife.com> (raw)
In-Reply-To: <20141121145226.2ac598af@annuminas.surriel.com>
[-- Attachment #1: Type: text/plain, Size: 1361 bytes --]
Hi Rik,
On 11/21/2014 08:52 PM, Rik van Riel wrote:
> When manipulating just one semaphore with semop, sem_lock only takes that
> single semaphore's lock. This creates a problem during initialization of
> the semaphore array, when the data structures used by sem_lock have not
> been set up yet. The sma->lock is already held by newary, and we just
> have to make sure everything else waits on that lock during initialization.
>
> Luckily it is easy to make sem_lock wait on the sma->lock, by pretending
> there is a complex operation in progress while the sma is being initialized.
That's not sufficient, as sma->sem_nsems is accessed before calling
sem_lock(), both within find_alloc_undo() and within semtimedop().
The root problem is that sma->sem_nsems and sma->sem_base are accessed
without any locks, this conflicts with the approach that sma starts to
exist as not yet initialized but locked and is unlocked after the
initialization is completed.
Attached is an idea. It did pass a few short tests.
What do you think?
With regards to affected kernels:
- wrong -EFBIG are possible since 3.10 (test for sma->sem_nsems moved
before taking the lock)
- kernel memory corruptions with 0-sized undo buffer allocation is
possible since 3.10, too.
(sem_lock before accessing sma->sem_nsems replaced with
sem_obtain_object_check).
--
Manfred
[-- Attachment #2: 0001-ipc-sem.c-Fully-initialize-sem_array-before-making-i.patch --]
[-- Type: text/x-patch, Size: 1642 bytes --]
>From fa928cdd6b5e032006f100f9689a5a4167c086e8 Mon Sep 17 00:00:00 2001
From: Manfred Spraul <manfred@colorfullife.com>
Date: Sun, 23 Nov 2014 19:08:57 +0100
Subject: [PATCH] ipc/sem.c: Fully initialize sem_array before making it
visible
ipc_addid() makes a new ipc identifier visible to everyone.
New objects start as locked, so that the caller can complete
the initialization after the call.
Within struct sem_array, at least sma->sem_base and sma->sem_nsems
are accessed without any locks, therefore this approach doesn't work.
Thus: Move the ipc_addid() to the end of the initialization.
Reported-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
---
ipc/sem.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/ipc/sem.c b/ipc/sem.c
index 454f6c6..53c3310 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -507,13 +507,6 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
return retval;
}
- id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
- if (id < 0) {
- ipc_rcu_putref(sma, sem_rcu_free);
- return id;
- }
- ns->used_sems += nsems;
-
sma->sem_base = (struct sem *) &sma[1];
for (i = 0; i < nsems; i++) {
@@ -528,6 +521,14 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
INIT_LIST_HEAD(&sma->list_id);
sma->sem_nsems = nsems;
sma->sem_ctime = get_seconds();
+
+ id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
+ if (id < 0) {
+ ipc_rcu_putref(sma, sem_rcu_free);
+ return id;
+ }
+ ns->used_sems += nsems;
+
sem_unlock(sma, -1);
rcu_read_unlock();
--
1.9.3
next prev parent reply other threads:[~2014-11-23 18:23 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-21 19:52 [PATCH] ipc,sem block sem_lock on sma->lock during sma initialization Rik van Riel
2014-11-21 20:07 ` Rafael Aquini
2014-11-21 20:09 ` Andrew Morton
2014-11-21 20:29 ` Rik van Riel
2014-11-21 20:42 ` Andrew Morton
2014-11-21 23:03 ` Rik van Riel
2014-11-22 0:56 ` Davidlohr Bueso
2014-11-22 3:40 ` Rik van Riel
2014-11-22 13:56 ` Manfred Spraul
2014-11-22 15:53 ` Rik van Riel
2014-11-22 19:14 ` Manfred Spraul
2014-11-22 20:14 ` Rik van Riel
2014-11-23 18:23 ` Manfred Spraul [this message]
2014-11-23 21:03 ` Rik van Riel
2014-11-23 21:36 ` Davidlohr Bueso
2014-11-24 10:41 ` Rafael Aquini
2014-11-24 20:49 ` Andrew Morton
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=54722639.1040605@colorfullife.com \
--to=manfred@colorfullife.com \
--cc=1vier1@web.de \
--cc=akpm@linux-foundation.org \
--cc=aquini@redhat.com \
--cc=davidlohr@hp.com \
--cc=linux-kernel@vger.kernel.org \
--cc=riel@redhat.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.