Jann Horn identified a racy access to p->mm in the global expedited
command of the membarrier system call.
The suggested fix is to hold the task_lock() around the accesses to
p->mm and to the mm_struct membarrier_state field to guarantee the
existence of the mm_struct.
Link: https://lore.kernel.org/lkml/CAG48ez2G8ctF8dHS42TF37pThfr3y0RNOOYTmxvACm4u8Yu3cw@mail.gmail.com
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
CC: Jann Horn <jannh@google.com>
CC: Thomas Gleixner <redacted>
CC: Peter Zijlstra (Intel) <peterz@infradead.org>
CC: Ingo Molnar <mingo@kernel.org>
CC: Andrea Parri <parri.andrea@gmail.com>
CC: Andrew Hunter <redacted>
CC: Andy Lutomirski <luto@kernel.org>
CC: Avi Kivity <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Boqun Feng <redacted>
CC: Dave Watson <redacted>
CC: David Sehr <redacted>
CC: Greg Hackmann <redacted>
CC: H. Peter Anvin <hpa@zytor.com>
CC: Linus Torvalds <torvalds@linux-foundation.org>
CC: Maged Michael <redacted>
CC: Michael Ellerman <mpe@ellerman.id.au>
CC: Paul E. McKenney <redacted>
CC: Paul Mackerras <redacted>
CC: Russell King <linux@armlinux.org.uk>
CC: Will Deacon <redacted>
CC: stable@vger.kernel.org # v4.16+
CC: linux-api@vger.kernel.org
---
kernel/sched/membarrier.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
On Mon, Jan 28, 2019 at 10:27 AM Mathieu Desnoyers
[off-list ref] wrote:
Jann Horn identified a racy access to p->mm in the global expedited
command of the membarrier system call.
The suggested fix is to hold the task_lock() around the accesses to
p->mm and to the mm_struct membarrier_state field to guarantee the
existence of the mm_struct.
Hmm. I think this is right. You shouldn't access another threads mm
pointer without proper locking.
That said, we *could* make the mm_cachep be SLAB_TYPESAFE_BY_RCU,
which would allow speculatively reading data off the mm pointer under
RCU. It might not be the *right* mm if somebody just did an exit, but
for things like this it shouldn't matter.
But if this is the only case that might care, it sounds like just
doing the proper locking is the right approach.
Linus
From: Paul E. McKenney <hidden> Date: 2019-01-28 20:46:28
On Mon, Jan 28, 2019 at 12:27:03PM -0800, Linus Torvalds wrote:
On Mon, Jan 28, 2019 at 10:27 AM Mathieu Desnoyers
[off-list ref] wrote:
quoted
Jann Horn identified a racy access to p->mm in the global expedited
command of the membarrier system call.
The suggested fix is to hold the task_lock() around the accesses to
p->mm and to the mm_struct membarrier_state field to guarantee the
existence of the mm_struct.
Hmm. I think this is right. You shouldn't access another threads mm
pointer without proper locking.
That said, we *could* make the mm_cachep be SLAB_TYPESAFE_BY_RCU,
which would allow speculatively reading data off the mm pointer under
RCU. It might not be the *right* mm if somebody just did an exit, but
for things like this it shouldn't matter.
That sounds much simpler and more effective than the contention-reduction
approach that I suggested. ;-)
Thanx, Paul
But if this is the only case that might care, it sounds like just
doing the proper locking is the right approach.
Linus
----- On Jan 28, 2019, at 3:46 PM, paulmck paulmck@linux.ibm.com wrote:
On Mon, Jan 28, 2019 at 12:27:03PM -0800, Linus Torvalds wrote:
quoted
On Mon, Jan 28, 2019 at 10:27 AM Mathieu Desnoyers
[off-list ref] wrote:
quoted
Jann Horn identified a racy access to p->mm in the global expedited
command of the membarrier system call.
The suggested fix is to hold the task_lock() around the accesses to
p->mm and to the mm_struct membarrier_state field to guarantee the
existence of the mm_struct.
Hmm. I think this is right. You shouldn't access another threads mm
pointer without proper locking.
That said, we *could* make the mm_cachep be SLAB_TYPESAFE_BY_RCU,
which would allow speculatively reading data off the mm pointer under
RCU. It might not be the *right* mm if somebody just did an exit, but
for things like this it shouldn't matter.
That sounds much simpler and more effective than the contention-reduction
approach that I suggested. ;-)
I'd be tempted to stick to the locking approach for a fix, and implement
Linus' type-safe mm_cachep idea if anyone complains about the overhead
of membarrier GLOBAL_EXPEDITED (and submit for a future merge window).
I tested the KASAN splat reproducer from Jann locally, and confirmed that
my patch fixes the issue it reproduces.
Please let me know if the task_lock() approach is OK as a fix for now.
I'm also awaiting a Tested-by from Jann before submitting this for real.
Thanks,
Mathieu
Thanx, Paul
quoted
But if this is the only case that might care, it sounds like just
doing the proper locking is the right approach.
Linus
From: Paul E. McKenney <hidden> Date: 2019-01-28 21:26:47
On Mon, Jan 28, 2019 at 04:07:26PM -0500, Mathieu Desnoyers wrote:
----- On Jan 28, 2019, at 3:46 PM, paulmck paulmck@linux.ibm.com wrote:
quoted
On Mon, Jan 28, 2019 at 12:27:03PM -0800, Linus Torvalds wrote:
quoted
On Mon, Jan 28, 2019 at 10:27 AM Mathieu Desnoyers
[off-list ref] wrote:
quoted
Jann Horn identified a racy access to p->mm in the global expedited
command of the membarrier system call.
The suggested fix is to hold the task_lock() around the accesses to
p->mm and to the mm_struct membarrier_state field to guarantee the
existence of the mm_struct.
Hmm. I think this is right. You shouldn't access another threads mm
pointer without proper locking.
That said, we *could* make the mm_cachep be SLAB_TYPESAFE_BY_RCU,
which would allow speculatively reading data off the mm pointer under
RCU. It might not be the *right* mm if somebody just did an exit, but
for things like this it shouldn't matter.
That sounds much simpler and more effective than the contention-reduction
approach that I suggested. ;-)
I'd be tempted to stick to the locking approach for a fix, and implement
Linus' type-safe mm_cachep idea if anyone complains about the overhead
of membarrier GLOBAL_EXPEDITED (and submit for a future merge window).
I tested the KASAN splat reproducer from Jann locally, and confirmed that
my patch fixes the issue it reproduces.
Please let me know if the task_lock() approach is OK as a fix for now.
Agreed, no need for added complexity until there is a clear need.
I'm also awaiting a Tested-by from Jann before submitting this for real.
Makes sense to me!
Thanx, Paul
Thanks,
Mathieu
quoted
Thanx, Paul
quoted
But if this is the only case that might care, it sounds like just
doing the proper locking is the right approach.
Linus
On Mon, Jan 28, 2019 at 7:27 PM Mathieu Desnoyers
[off-list ref] wrote:
Jann Horn identified a racy access to p->mm in the global expedited
command of the membarrier system call.
The suggested fix is to hold the task_lock() around the accesses to
p->mm and to the mm_struct membarrier_state field to guarantee the
existence of the mm_struct.
Link: https://lore.kernel.org/lkml/CAG48ez2G8ctF8dHS42TF37pThfr3y0RNOOYTmxvACm4u8Yu3cw@mail.gmail.com
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
The patch looks good to me, and to be sure, I've also given it a spin
- I can't trigger a splat anymore. You can add:
Tested-by: Jann Horn <jannh@google.com>