linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] x86: unwinder/entry fixes
@ 2017-01-09 18:00 Josh Poimboeuf
  2017-01-09 18:00 ` [PATCH 1/4] x86/unwind: silence warnings for non-current tasks Josh Poimboeuf
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Josh Poimboeuf @ 2017-01-09 18:00 UTC (permalink / raw)
  To: x86
  Cc: Dave Jones, Dmitry Vyukov, Miroslav Benes, Andy Lutomirski,
	Brian Gerst, linux-kernel

Some unwinder-related fixes for some issues reported over the holidays.
The first three patches are pretty minor, but note the last patch
modifies entry code.

Josh Poimboeuf (4):
  x86/unwind: silence warnings for non-current tasks
  x86/unwind: disable KASAN checks for non-current tasks
  x86/unwind: include __schedule() in stack traces
  x86/entry: fix the end of the stack for newly forked tasks

 arch/x86/entry/entry_32.S         | 30 +++++++++++-------------------
 arch/x86/entry/entry_64.S         | 11 +++++++----
 arch/x86/include/asm/stacktrace.h |  2 +-
 arch/x86/include/asm/switch_to.h  | 10 +++++++++-
 arch/x86/kernel/unwind_frame.c    | 30 ++++++++++++++++++++++++++++--
 5 files changed, 56 insertions(+), 27 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/4] x86/unwind: silence warnings for non-current tasks
  2017-01-09 18:00 [PATCH 0/4] x86: unwinder/entry fixes Josh Poimboeuf
@ 2017-01-09 18:00 ` Josh Poimboeuf
  2017-01-12 10:04   ` [tip:x86/urgent] x86/unwind: Silence " tip-bot for Josh Poimboeuf
  2017-01-09 18:00 ` [PATCH 2/4] x86/unwind: disable KASAN checks " Josh Poimboeuf
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Josh Poimboeuf @ 2017-01-09 18:00 UTC (permalink / raw)
  To: x86
  Cc: Dave Jones, Dmitry Vyukov, Miroslav Benes, Andy Lutomirski,
	Brian Gerst, linux-kernel

There are a handful of callers to save_stack_trace_tsk() and
show_stack() which try to unwind the stack of a task other than current.
In such cases, it's remotely possible that the task is running on one
CPU while the unwinder is reading its stack from another CPU, causing
the unwinder to see stack corruption.

These cases seem to be mostly harmless.  The unwinder has checks which
prevent it from following bad pointers beyond the bounds of the stack.
So it's not really a bug as long as the caller understands that
unwinding another task will not always succeed.

Since stack "corruption" on another task's stack isn't necessarily a
bug, silence the warnings when unwinding tasks other than current.

Reported-by: Dave Jones <davej@codemonkey.org.uk>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 arch/x86/kernel/unwind_frame.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c
index 4443e49..195eebf 100644
--- a/arch/x86/kernel/unwind_frame.c
+++ b/arch/x86/kernel/unwind_frame.c
@@ -207,6 +207,16 @@ bool unwind_next_frame(struct unwind_state *state)
 	return true;
 
 bad_address:
+	/*
+	 * When unwinding a non-current task, the task might actually be
+	 * running on another CPU, in which case it could be modifying its
+	 * stack while we're reading it.  This is generally not a problem and
+	 * can be ignored as long as the caller understands that unwinding
+	 * another task will not always succeed.
+	 */
+	if (state->task != current)
+		goto the_end;
+
 	if (state->regs) {
 		printk_deferred_once(KERN_WARNING
 			"WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n",
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/4] x86/unwind: disable KASAN checks for non-current tasks
  2017-01-09 18:00 [PATCH 0/4] x86: unwinder/entry fixes Josh Poimboeuf
  2017-01-09 18:00 ` [PATCH 1/4] x86/unwind: silence warnings for non-current tasks Josh Poimboeuf
@ 2017-01-09 18:00 ` Josh Poimboeuf
  2017-01-12 10:04   ` [tip:x86/urgent] x86/unwind: Disable " tip-bot for Josh Poimboeuf
  2017-01-09 18:00 ` [PATCH 3/4] x86/unwind: include __schedule() in stack traces Josh Poimboeuf
  2017-01-09 18:00 ` [PATCH 4/4] x86/entry: fix the end of the stack for newly forked tasks Josh Poimboeuf
  3 siblings, 1 reply; 12+ messages in thread
From: Josh Poimboeuf @ 2017-01-09 18:00 UTC (permalink / raw)
  To: x86
  Cc: Dave Jones, Dmitry Vyukov, Miroslav Benes, Andy Lutomirski,
	Brian Gerst, linux-kernel

There are a handful of callers to save_stack_trace_tsk() and
show_stack() which try to unwind the stack of a task other than current.
In such cases, it's remotely possible that the task is running on one
CPU while the unwinder is reading its stack from another CPU, causing
the unwinder to see stack corruption.

These cases seem to be mostly harmless.  The unwinder has checks which
prevent it from following bad pointers beyond the bounds of the stack.
So it's not really a bug as long as the caller understands that
unwinding another task will not always succeed.

In such cases, it's possible that the unwinder may read a KASAN-poisoned
region of the stack.  Account for that by using READ_ONCE_NOCHECK when
reading the stack of another task.

Use READ_ONCE when reading the stack of the current task, since KASAN
warnings can still be useful for finding bugs in that case.

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 arch/x86/include/asm/stacktrace.h |  5 ++++-
 arch/x86/kernel/unwind_frame.c    | 20 ++++++++++++++++++--
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
index a3269c8..20ce3db 100644
--- a/arch/x86/include/asm/stacktrace.h
+++ b/arch/x86/include/asm/stacktrace.h
@@ -52,13 +52,16 @@ static inline bool on_stack(struct stack_info *info, void *addr, size_t len)
 static inline unsigned long *
 get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
 {
+	struct inactive_task_frame *frame;
+
 	if (regs)
 		return (unsigned long *)regs->bp;
 
 	if (task == current)
 		return __builtin_frame_address(0);
 
-	return (unsigned long *)((struct inactive_task_frame *)task->thread.sp)->bp;
+	frame = (struct inactive_task_frame *)task->thread.sp;
+	return (unsigned long *)READ_ONCE_NOCHECK(frame->bp);
 }
 #else
 static inline unsigned long *
diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c
index 195eebf..23d1556 100644
--- a/arch/x86/kernel/unwind_frame.c
+++ b/arch/x86/kernel/unwind_frame.c
@@ -6,6 +6,21 @@
 
 #define FRAME_HEADER_SIZE (sizeof(long) * 2)
 
+/*
+ * This disables KASAN checking when reading a value from another task's stack,
+ * since the other task could be running on another CPU and could have poisoned
+ * the stack in the meantime.
+ */
+#define READ_ONCE_TASK_STACK(task, x)			\
+({							\
+	unsigned long val;				\
+	if (task == current)				\
+		val = READ_ONCE(x);			\
+	else						\
+		val = READ_ONCE_NOCHECK(x);		\
+	val;						\
+})
+
 static void unwind_dump(struct unwind_state *state, unsigned long *sp)
 {
 	static bool dumped_before = false;
@@ -48,7 +63,8 @@ unsigned long unwind_get_return_address(struct unwind_state *state)
 	if (state->regs && user_mode(state->regs))
 		return 0;
 
-	addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p,
+	addr = READ_ONCE_TASK_STACK(state->task, *addr_p);
+	addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, addr,
 				     addr_p);
 
 	return __kernel_text_address(addr) ? addr : 0;
@@ -162,7 +178,7 @@ bool unwind_next_frame(struct unwind_state *state)
 	if (state->regs)
 		next_bp = (unsigned long *)state->regs->bp;
 	else
-		next_bp = (unsigned long *)*state->bp;
+		next_bp = (unsigned long *)READ_ONCE_TASK_STACK(state->task,*state->bp);
 
 	/* is the next frame pointer an encoded pointer to pt_regs? */
 	regs = decode_frame_pointer(next_bp);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/4] x86/unwind: include __schedule() in stack traces
  2017-01-09 18:00 [PATCH 0/4] x86: unwinder/entry fixes Josh Poimboeuf
  2017-01-09 18:00 ` [PATCH 1/4] x86/unwind: silence warnings for non-current tasks Josh Poimboeuf
  2017-01-09 18:00 ` [PATCH 2/4] x86/unwind: disable KASAN checks " Josh Poimboeuf
@ 2017-01-09 18:00 ` Josh Poimboeuf
  2017-01-10 10:14   ` Miroslav Benes
  2017-01-12 10:05   ` [tip:x86/urgent] x86/unwind: Include " tip-bot for Josh Poimboeuf
  2017-01-09 18:00 ` [PATCH 4/4] x86/entry: fix the end of the stack for newly forked tasks Josh Poimboeuf
  3 siblings, 2 replies; 12+ messages in thread
From: Josh Poimboeuf @ 2017-01-09 18:00 UTC (permalink / raw)
  To: x86
  Cc: Dave Jones, Dmitry Vyukov, Miroslav Benes, Andy Lutomirski,
	Brian Gerst, linux-kernel

In the following commit:

  0100301bfdf5 ("sched/x86: Rewrite the switch_to() code")

... the layout of the 'inactive_task_frame' struct was designed to have
a frame pointer header embedded in it, so that the unwinder could use
the 'bp' and 'ret_addr' fields to report __schedule() on the stack (or
ret_from_fork() for newly forked tasks which haven't actually run yet).

Finish the job by changing get_frame_pointer() to return a pointer to
inactive_task_frame's 'bp' field rather than 'bp' itself.  This allows
the unwinder to start one frame higher on the stack, so that it properly
reports __schedule().

Reported-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 arch/x86/include/asm/stacktrace.h |  5 +----
 arch/x86/include/asm/switch_to.h  | 10 +++++++++-
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
index 20ce3db..2e41c50 100644
--- a/arch/x86/include/asm/stacktrace.h
+++ b/arch/x86/include/asm/stacktrace.h
@@ -52,16 +52,13 @@ static inline bool on_stack(struct stack_info *info, void *addr, size_t len)
 static inline unsigned long *
 get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
 {
-	struct inactive_task_frame *frame;
-
 	if (regs)
 		return (unsigned long *)regs->bp;
 
 	if (task == current)
 		return __builtin_frame_address(0);
 
-	frame = (struct inactive_task_frame *)task->thread.sp;
-	return (unsigned long *)READ_ONCE_NOCHECK(frame->bp);
+	return &((struct inactive_task_frame *)task->thread.sp)->bp;
 }
 #else
 static inline unsigned long *
diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h
index 5cb436a..fcc5cd3 100644
--- a/arch/x86/include/asm/switch_to.h
+++ b/arch/x86/include/asm/switch_to.h
@@ -36,7 +36,10 @@ static inline void prepare_switch_to(struct task_struct *prev,
 
 asmlinkage void ret_from_fork(void);
 
-/* data that is pointed to by thread.sp */
+/*
+ * This is the structure pointed to by thread.sp for an inactive task.  The
+ * order of the fields must match the code in __switch_to_asm().
+ */
 struct inactive_task_frame {
 #ifdef CONFIG_X86_64
 	unsigned long r15;
@@ -48,6 +51,11 @@ struct inactive_task_frame {
 	unsigned long di;
 #endif
 	unsigned long bx;
+
+	/*
+	 * These two fields must be together.  They form a stack frame header,
+	 * needed by get_frame_pointer().
+	 */
 	unsigned long bp;
 	unsigned long ret_addr;
 };
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/4] x86/entry: fix the end of the stack for newly forked tasks
  2017-01-09 18:00 [PATCH 0/4] x86: unwinder/entry fixes Josh Poimboeuf
                   ` (2 preceding siblings ...)
  2017-01-09 18:00 ` [PATCH 3/4] x86/unwind: include __schedule() in stack traces Josh Poimboeuf
@ 2017-01-09 18:00 ` Josh Poimboeuf
  2017-01-12 10:05   ` [tip:x86/urgent] x86/entry: Fix " tip-bot for Josh Poimboeuf
  3 siblings, 1 reply; 12+ messages in thread
From: Josh Poimboeuf @ 2017-01-09 18:00 UTC (permalink / raw)
  To: x86
  Cc: Dave Jones, Dmitry Vyukov, Miroslav Benes, Andy Lutomirski,
	Brian Gerst, linux-kernel

When unwinding a task, the end of the stack is always at the same offset
right below the saved pt_regs, regardless of which syscall was used to
enter the kernel.  That convention allows the unwinder to verify that a
stack is sane.

However, newly forked tasks don't always follow that convention, as
reported by the following unwinder warning seen by Dave Jones:

  WARNING: kernel stack frame pointer at ffffc90001443f30 in kworker/u8:8:30468 has bad value           (null)

The warning was due to the following call chain:

  (ftrace handler)
  call_usermodehelper_exec_async+0x5/0x140
  ret_from_fork+0x22/0x30

The problem is that ret_from_fork() doesn't create a stack frame before
calling other functions.  Fix that by carefully using the frame pointer
macros.

In addition to conforming to the end of stack convention, this also
makes related stack traces more sensible by making it clear to the user
that ret_from_fork() was involved.

Reported-by: Dave Jones <davej@codemonkey.org.uk>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 arch/x86/entry/entry_32.S | 30 +++++++++++-------------------
 arch/x86/entry/entry_64.S | 11 +++++++----
 2 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index 701d29f..57f7ec3 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -255,23 +255,6 @@ ENTRY(__switch_to_asm)
 END(__switch_to_asm)
 
 /*
- * The unwinder expects the last frame on the stack to always be at the same
- * offset from the end of the page, which allows it to validate the stack.
- * Calling schedule_tail() directly would break that convention because its an
- * asmlinkage function so its argument has to be pushed on the stack.  This
- * wrapper creates a proper "end of stack" frame header before the call.
- */
-ENTRY(schedule_tail_wrapper)
-	FRAME_BEGIN
-
-	pushl	%eax
-	call	schedule_tail
-	popl	%eax
-
-	FRAME_END
-	ret
-ENDPROC(schedule_tail_wrapper)
-/*
  * A newly forked process directly context switches into this address.
  *
  * eax: prev task we switched from
@@ -279,15 +262,24 @@ ENDPROC(schedule_tail_wrapper)
  * edi: kernel thread arg
  */
 ENTRY(ret_from_fork)
-	call	schedule_tail_wrapper
+	FRAME_BEGIN		/* help unwinder find end of stack */
+
+	/*
+	 * schedule_tail() is asmlinkage so we have to put its 'prev' argument
+	 * on the stack.
+	 */
+	pushl	%eax
+	call	schedule_tail
+	popl	%eax
 
 	testl	%ebx, %ebx
 	jnz	1f		/* kernel threads are uncommon */
 
 2:
 	/* When we fork, we trace the syscall return in the child, too. */
-	movl    %esp, %eax
+	leal	FRAME_OFFSET(%esp), %eax
 	call    syscall_return_slowpath
+	FRAME_END
 	jmp     restore_all
 
 	/* kernel thread */
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 5b21970..044d18e 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -36,6 +36,7 @@
 #include <asm/smap.h>
 #include <asm/pgtable_types.h>
 #include <asm/export.h>
+#include <asm/frame.h>
 #include <linux/err.h>
 
 .code64
@@ -408,17 +409,19 @@ END(__switch_to_asm)
  * r12: kernel thread arg
  */
 ENTRY(ret_from_fork)
+	FRAME_BEGIN			/* help unwinder find end of stack */
 	movq	%rax, %rdi
-	call	schedule_tail			/* rdi: 'prev' task parameter */
+	call	schedule_tail		/* rdi: 'prev' task parameter */
 
-	testq	%rbx, %rbx			/* from kernel_thread? */
-	jnz	1f				/* kernel threads are uncommon */
+	testq	%rbx, %rbx		/* from kernel_thread? */
+	jnz	1f			/* kernel threads are uncommon */
 
 2:
-	movq	%rsp, %rdi
+	leaq	FRAME_OFFSET(%rsp),%rdi	/* pt_regs pointer */
 	call	syscall_return_slowpath	/* returns with IRQs disabled */
 	TRACE_IRQS_ON			/* user mode is traced as IRQS on */
 	SWAPGS
+	FRAME_END
 	jmp	restore_regs_and_iret
 
 1:
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] x86/unwind: include __schedule() in stack traces
  2017-01-09 18:00 ` [PATCH 3/4] x86/unwind: include __schedule() in stack traces Josh Poimboeuf
@ 2017-01-10 10:14   ` Miroslav Benes
  2017-01-10 17:28     ` Josh Poimboeuf
  2017-01-12 10:05   ` [tip:x86/urgent] x86/unwind: Include " tip-bot for Josh Poimboeuf
  1 sibling, 1 reply; 12+ messages in thread
From: Miroslav Benes @ 2017-01-10 10:14 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: x86, Dave Jones, Dmitry Vyukov, Andy Lutomirski, Brian Gerst,
	linux-kernel

On Mon, 9 Jan 2017, Josh Poimboeuf wrote:

> In the following commit:
> 
>   0100301bfdf5 ("sched/x86: Rewrite the switch_to() code")
> 
> ... the layout of the 'inactive_task_frame' struct was designed to have
> a frame pointer header embedded in it, so that the unwinder could use
> the 'bp' and 'ret_addr' fields to report __schedule() on the stack (or
> ret_from_fork() for newly forked tasks which haven't actually run yet).
> 
> Finish the job by changing get_frame_pointer() to return a pointer to
> inactive_task_frame's 'bp' field rather than 'bp' itself.  This allows
> the unwinder to start one frame higher on the stack, so that it properly
> reports __schedule().
> 
> Reported-by: Miroslav Benes <mbenes@suse.cz>

You can also add my

Tested-by: Miroslav Benes <mbenes@suse.cz>

One ignorant question below.

> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
> ---
>  arch/x86/include/asm/stacktrace.h |  5 +----
>  arch/x86/include/asm/switch_to.h  | 10 +++++++++-
>  2 files changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
> index 20ce3db..2e41c50 100644
> --- a/arch/x86/include/asm/stacktrace.h
> +++ b/arch/x86/include/asm/stacktrace.h
> @@ -52,16 +52,13 @@ static inline bool on_stack(struct stack_info *info, void *addr, size_t len)
>  static inline unsigned long *
>  get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
>  {
> -	struct inactive_task_frame *frame;
> -
>  	if (regs)
>  		return (unsigned long *)regs->bp;
>  
>  	if (task == current)
>  		return __builtin_frame_address(0);
>  
> -	frame = (struct inactive_task_frame *)task->thread.sp;
> -	return (unsigned long *)READ_ONCE_NOCHECK(frame->bp);
> +	return &((struct inactive_task_frame *)task->thread.sp)->bp;

You effectively remove one of the changes from the previous patch - 
READ_ONCE_NOCHECK. Is it intentional?

Regards,
Miroslav

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] x86/unwind: include __schedule() in stack traces
  2017-01-10 10:14   ` Miroslav Benes
@ 2017-01-10 17:28     ` Josh Poimboeuf
  2017-01-10 20:02       ` Miroslav Benes
  0 siblings, 1 reply; 12+ messages in thread
From: Josh Poimboeuf @ 2017-01-10 17:28 UTC (permalink / raw)
  To: Miroslav Benes
  Cc: x86, Dave Jones, Dmitry Vyukov, Andy Lutomirski, Brian Gerst,
	linux-kernel

On Tue, Jan 10, 2017 at 11:14:51AM +0100, Miroslav Benes wrote:
> On Mon, 9 Jan 2017, Josh Poimboeuf wrote:
> > Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
> > ---
> >  arch/x86/include/asm/stacktrace.h |  5 +----
> >  arch/x86/include/asm/switch_to.h  | 10 +++++++++-
> >  2 files changed, 10 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
> > index 20ce3db..2e41c50 100644
> > --- a/arch/x86/include/asm/stacktrace.h
> > +++ b/arch/x86/include/asm/stacktrace.h
> > @@ -52,16 +52,13 @@ static inline bool on_stack(struct stack_info *info, void *addr, size_t len)
> >  static inline unsigned long *
> >  get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
> >  {
> > -	struct inactive_task_frame *frame;
> > -
> >  	if (regs)
> >  		return (unsigned long *)regs->bp;
> >  
> >  	if (task == current)
> >  		return __builtin_frame_address(0);
> >  
> > -	frame = (struct inactive_task_frame *)task->thread.sp;
> > -	return (unsigned long *)READ_ONCE_NOCHECK(frame->bp);
> > +	return &((struct inactive_task_frame *)task->thread.sp)->bp;
> 
> You effectively remove one of the changes from the previous patch - 
> READ_ONCE_NOCHECK. Is it intentional?

Yes, notice that it's no longer reading the value of bp on the stack.
It's instead getting a pointer to it.  Since there's no longer a stack
access, READ_ONCE_NOCHECK is no longer needed.

-- 
Josh

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] x86/unwind: include __schedule() in stack traces
  2017-01-10 17:28     ` Josh Poimboeuf
@ 2017-01-10 20:02       ` Miroslav Benes
  0 siblings, 0 replies; 12+ messages in thread
From: Miroslav Benes @ 2017-01-10 20:02 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: x86, Dave Jones, Dmitry Vyukov, Andy Lutomirski, Brian Gerst,
	linux-kernel

On Tue, 10 Jan 2017, Josh Poimboeuf wrote:

> On Tue, Jan 10, 2017 at 11:14:51AM +0100, Miroslav Benes wrote:
> > On Mon, 9 Jan 2017, Josh Poimboeuf wrote:
> > > Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
> > > ---
> > >  arch/x86/include/asm/stacktrace.h |  5 +----
> > >  arch/x86/include/asm/switch_to.h  | 10 +++++++++-
> > >  2 files changed, 10 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
> > > index 20ce3db..2e41c50 100644
> > > --- a/arch/x86/include/asm/stacktrace.h
> > > +++ b/arch/x86/include/asm/stacktrace.h
> > > @@ -52,16 +52,13 @@ static inline bool on_stack(struct stack_info *info, void *addr, size_t len)
> > >  static inline unsigned long *
> > >  get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
> > >  {
> > > -	struct inactive_task_frame *frame;
> > > -
> > >  	if (regs)
> > >  		return (unsigned long *)regs->bp;
> > >  
> > >  	if (task == current)
> > >  		return __builtin_frame_address(0);
> > >  
> > > -	frame = (struct inactive_task_frame *)task->thread.sp;
> > > -	return (unsigned long *)READ_ONCE_NOCHECK(frame->bp);
> > > +	return &((struct inactive_task_frame *)task->thread.sp)->bp;
> > 
> > You effectively remove one of the changes from the previous patch - 
> > READ_ONCE_NOCHECK. Is it intentional?
> 
> Yes, notice that it's no longer reading the value of bp on the stack.
> It's instead getting a pointer to it.  Since there's no longer a stack
> access, READ_ONCE_NOCHECK is no longer needed.

Oh, of course. Sorry for the noise.

Miroslav

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [tip:x86/urgent] x86/unwind: Silence warnings for non-current tasks
  2017-01-09 18:00 ` [PATCH 1/4] x86/unwind: silence warnings for non-current tasks Josh Poimboeuf
@ 2017-01-12 10:04   ` tip-bot for Josh Poimboeuf
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot for Josh Poimboeuf @ 2017-01-12 10:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: luto, dvlasenk, mingo, peterz, torvalds, dvyukov, bp, tglx, luto,
	mbenes, jpoimboe, hpa, linux-kernel, brgerst, davej

Commit-ID:  900742d89c1b4e04bd373aec8470b88e183f08ca
Gitweb:     http://git.kernel.org/tip/900742d89c1b4e04bd373aec8470b88e183f08ca
Author:     Josh Poimboeuf <jpoimboe@redhat.com>
AuthorDate: Mon, 9 Jan 2017 12:00:22 -0600
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 12 Jan 2017 09:28:27 +0100

x86/unwind: Silence warnings for non-current tasks

There are a handful of callers to save_stack_trace_tsk() and
show_stack() which try to unwind the stack of a task other than current.
In such cases, it's remotely possible that the task is running on one
CPU while the unwinder is reading its stack from another CPU, causing
the unwinder to see stack corruption.

These cases seem to be mostly harmless.  The unwinder has checks which
prevent it from following bad pointers beyond the bounds of the stack.
So it's not really a bug as long as the caller understands that
unwinding another task will not always succeed.

Since stack "corruption" on another task's stack isn't necessarily a
bug, silence the warnings when unwinding tasks other than current.

Reported-by: Dave Jones <davej@codemonkey.org.uk>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Miroslav Benes <mbenes@suse.cz>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/00d8c50eea3446c1524a2a755397a3966629354c.1483978430.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/unwind_frame.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c
index 4443e49..195eebf 100644
--- a/arch/x86/kernel/unwind_frame.c
+++ b/arch/x86/kernel/unwind_frame.c
@@ -207,6 +207,16 @@ bool unwind_next_frame(struct unwind_state *state)
 	return true;
 
 bad_address:
+	/*
+	 * When unwinding a non-current task, the task might actually be
+	 * running on another CPU, in which case it could be modifying its
+	 * stack while we're reading it.  This is generally not a problem and
+	 * can be ignored as long as the caller understands that unwinding
+	 * another task will not always succeed.
+	 */
+	if (state->task != current)
+		goto the_end;
+
 	if (state->regs) {
 		printk_deferred_once(KERN_WARNING
 			"WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n",

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [tip:x86/urgent] x86/unwind: Disable KASAN checks for non-current tasks
  2017-01-09 18:00 ` [PATCH 2/4] x86/unwind: disable KASAN checks " Josh Poimboeuf
@ 2017-01-12 10:04   ` tip-bot for Josh Poimboeuf
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot for Josh Poimboeuf @ 2017-01-12 10:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: dvlasenk, linux-kernel, luto, peterz, mbenes, davej, dvyukov,
	tglx, hpa, brgerst, jpoimboe, luto, bp, mingo, torvalds

Commit-ID:  84936118bdf37bda513d4a361c38181a216427e0
Gitweb:     http://git.kernel.org/tip/84936118bdf37bda513d4a361c38181a216427e0
Author:     Josh Poimboeuf <jpoimboe@redhat.com>
AuthorDate: Mon, 9 Jan 2017 12:00:23 -0600
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 12 Jan 2017 09:28:27 +0100

x86/unwind: Disable KASAN checks for non-current tasks

There are a handful of callers to save_stack_trace_tsk() and
show_stack() which try to unwind the stack of a task other than current.
In such cases, it's remotely possible that the task is running on one
CPU while the unwinder is reading its stack from another CPU, causing
the unwinder to see stack corruption.

These cases seem to be mostly harmless.  The unwinder has checks which
prevent it from following bad pointers beyond the bounds of the stack.
So it's not really a bug as long as the caller understands that
unwinding another task will not always succeed.

In such cases, it's possible that the unwinder may read a KASAN-poisoned
region of the stack.  Account for that by using READ_ONCE_NOCHECK() when
reading the stack of another task.

Use READ_ONCE() when reading the stack of the current task, since KASAN
warnings can still be useful for finding bugs in that case.

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Jones <davej@codemonkey.org.uk>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Miroslav Benes <mbenes@suse.cz>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/4c575eb288ba9f73d498dfe0acde2f58674598f1.1483978430.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/stacktrace.h |  5 ++++-
 arch/x86/kernel/unwind_frame.c    | 20 ++++++++++++++++++--
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
index a3269c8..20ce3db 100644
--- a/arch/x86/include/asm/stacktrace.h
+++ b/arch/x86/include/asm/stacktrace.h
@@ -52,13 +52,16 @@ static inline bool on_stack(struct stack_info *info, void *addr, size_t len)
 static inline unsigned long *
 get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
 {
+	struct inactive_task_frame *frame;
+
 	if (regs)
 		return (unsigned long *)regs->bp;
 
 	if (task == current)
 		return __builtin_frame_address(0);
 
-	return (unsigned long *)((struct inactive_task_frame *)task->thread.sp)->bp;
+	frame = (struct inactive_task_frame *)task->thread.sp;
+	return (unsigned long *)READ_ONCE_NOCHECK(frame->bp);
 }
 #else
 static inline unsigned long *
diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c
index 195eebf..23d1556 100644
--- a/arch/x86/kernel/unwind_frame.c
+++ b/arch/x86/kernel/unwind_frame.c
@@ -6,6 +6,21 @@
 
 #define FRAME_HEADER_SIZE (sizeof(long) * 2)
 
+/*
+ * This disables KASAN checking when reading a value from another task's stack,
+ * since the other task could be running on another CPU and could have poisoned
+ * the stack in the meantime.
+ */
+#define READ_ONCE_TASK_STACK(task, x)			\
+({							\
+	unsigned long val;				\
+	if (task == current)				\
+		val = READ_ONCE(x);			\
+	else						\
+		val = READ_ONCE_NOCHECK(x);		\
+	val;						\
+})
+
 static void unwind_dump(struct unwind_state *state, unsigned long *sp)
 {
 	static bool dumped_before = false;
@@ -48,7 +63,8 @@ unsigned long unwind_get_return_address(struct unwind_state *state)
 	if (state->regs && user_mode(state->regs))
 		return 0;
 
-	addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p,
+	addr = READ_ONCE_TASK_STACK(state->task, *addr_p);
+	addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, addr,
 				     addr_p);
 
 	return __kernel_text_address(addr) ? addr : 0;
@@ -162,7 +178,7 @@ bool unwind_next_frame(struct unwind_state *state)
 	if (state->regs)
 		next_bp = (unsigned long *)state->regs->bp;
 	else
-		next_bp = (unsigned long *)*state->bp;
+		next_bp = (unsigned long *)READ_ONCE_TASK_STACK(state->task,*state->bp);
 
 	/* is the next frame pointer an encoded pointer to pt_regs? */
 	regs = decode_frame_pointer(next_bp);

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [tip:x86/urgent] x86/unwind: Include __schedule() in stack traces
  2017-01-09 18:00 ` [PATCH 3/4] x86/unwind: include __schedule() in stack traces Josh Poimboeuf
  2017-01-10 10:14   ` Miroslav Benes
@ 2017-01-12 10:05   ` tip-bot for Josh Poimboeuf
  1 sibling, 0 replies; 12+ messages in thread
From: tip-bot for Josh Poimboeuf @ 2017-01-12 10:05 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: jpoimboe, torvalds, tglx, dvyukov, luto, mingo, mbenes,
	linux-kernel, hpa, bp, luto, dvlasenk, davej, peterz, brgerst

Commit-ID:  2c96b2fe9c57b4267c3f0a680d82d7cc52e1c447
Gitweb:     http://git.kernel.org/tip/2c96b2fe9c57b4267c3f0a680d82d7cc52e1c447
Author:     Josh Poimboeuf <jpoimboe@redhat.com>
AuthorDate: Mon, 9 Jan 2017 12:00:24 -0600
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 12 Jan 2017 09:28:28 +0100

x86/unwind: Include __schedule() in stack traces

In the following commit:

  0100301bfdf5 ("sched/x86: Rewrite the switch_to() code")

... the layout of the 'inactive_task_frame' struct was designed to have
a frame pointer header embedded in it, so that the unwinder could use
the 'bp' and 'ret_addr' fields to report __schedule() on the stack (or
ret_from_fork() for newly forked tasks which haven't actually run yet).

Finish the job by changing get_frame_pointer() to return a pointer to
inactive_task_frame's 'bp' field rather than 'bp' itself.  This allows
the unwinder to start one frame higher on the stack, so that it properly
reports __schedule().

Reported-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Jones <davej@codemonkey.org.uk>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/598e9f7505ed0aba86e8b9590aa528c6c7ae8dcd.1483978430.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/stacktrace.h |  5 +----
 arch/x86/include/asm/switch_to.h  | 10 +++++++++-
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
index 20ce3db..2e41c50 100644
--- a/arch/x86/include/asm/stacktrace.h
+++ b/arch/x86/include/asm/stacktrace.h
@@ -52,16 +52,13 @@ static inline bool on_stack(struct stack_info *info, void *addr, size_t len)
 static inline unsigned long *
 get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
 {
-	struct inactive_task_frame *frame;
-
 	if (regs)
 		return (unsigned long *)regs->bp;
 
 	if (task == current)
 		return __builtin_frame_address(0);
 
-	frame = (struct inactive_task_frame *)task->thread.sp;
-	return (unsigned long *)READ_ONCE_NOCHECK(frame->bp);
+	return &((struct inactive_task_frame *)task->thread.sp)->bp;
 }
 #else
 static inline unsigned long *
diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h
index 5cb436a..fcc5cd3 100644
--- a/arch/x86/include/asm/switch_to.h
+++ b/arch/x86/include/asm/switch_to.h
@@ -36,7 +36,10 @@ static inline void prepare_switch_to(struct task_struct *prev,
 
 asmlinkage void ret_from_fork(void);
 
-/* data that is pointed to by thread.sp */
+/*
+ * This is the structure pointed to by thread.sp for an inactive task.  The
+ * order of the fields must match the code in __switch_to_asm().
+ */
 struct inactive_task_frame {
 #ifdef CONFIG_X86_64
 	unsigned long r15;
@@ -48,6 +51,11 @@ struct inactive_task_frame {
 	unsigned long di;
 #endif
 	unsigned long bx;
+
+	/*
+	 * These two fields must be together.  They form a stack frame header,
+	 * needed by get_frame_pointer().
+	 */
 	unsigned long bp;
 	unsigned long ret_addr;
 };

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [tip:x86/urgent] x86/entry: Fix the end of the stack for newly forked tasks
  2017-01-09 18:00 ` [PATCH 4/4] x86/entry: fix the end of the stack for newly forked tasks Josh Poimboeuf
@ 2017-01-12 10:05   ` tip-bot for Josh Poimboeuf
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot for Josh Poimboeuf @ 2017-01-12 10:05 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mbenes, dvlasenk, davej, mingo, brgerst, bp, hpa, luto, luto,
	linux-kernel, tglx, peterz, torvalds, dvyukov, jpoimboe

Commit-ID:  ff3f7e2475bbf9201e95824e72698fcdc5c3d47a
Gitweb:     http://git.kernel.org/tip/ff3f7e2475bbf9201e95824e72698fcdc5c3d47a
Author:     Josh Poimboeuf <jpoimboe@redhat.com>
AuthorDate: Mon, 9 Jan 2017 12:00:25 -0600
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 12 Jan 2017 09:28:29 +0100

x86/entry: Fix the end of the stack for newly forked tasks

When unwinding a task, the end of the stack is always at the same offset
right below the saved pt_regs, regardless of which syscall was used to
enter the kernel.  That convention allows the unwinder to verify that a
stack is sane.

However, newly forked tasks don't always follow that convention, as
reported by the following unwinder warning seen by Dave Jones:

  WARNING: kernel stack frame pointer at ffffc90001443f30 in kworker/u8:8:30468 has bad value           (null)

The warning was due to the following call chain:

  (ftrace handler)
  call_usermodehelper_exec_async+0x5/0x140
  ret_from_fork+0x22/0x30

The problem is that ret_from_fork() doesn't create a stack frame before
calling other functions.  Fix that by carefully using the frame pointer
macros.

In addition to conforming to the end of stack convention, this also
makes related stack traces more sensible by making it clear to the user
that ret_from_fork() was involved.

Reported-by: Dave Jones <davej@codemonkey.org.uk>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Miroslav Benes <mbenes@suse.cz>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/8854cdaab980e9700a81e9ebf0d4238e4bbb68ef.1483978430.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/entry/entry_32.S | 30 +++++++++++-------------------
 arch/x86/entry/entry_64.S | 11 +++++++----
 2 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index 701d29f..57f7ec3 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -255,23 +255,6 @@ ENTRY(__switch_to_asm)
 END(__switch_to_asm)
 
 /*
- * The unwinder expects the last frame on the stack to always be at the same
- * offset from the end of the page, which allows it to validate the stack.
- * Calling schedule_tail() directly would break that convention because its an
- * asmlinkage function so its argument has to be pushed on the stack.  This
- * wrapper creates a proper "end of stack" frame header before the call.
- */
-ENTRY(schedule_tail_wrapper)
-	FRAME_BEGIN
-
-	pushl	%eax
-	call	schedule_tail
-	popl	%eax
-
-	FRAME_END
-	ret
-ENDPROC(schedule_tail_wrapper)
-/*
  * A newly forked process directly context switches into this address.
  *
  * eax: prev task we switched from
@@ -279,15 +262,24 @@ ENDPROC(schedule_tail_wrapper)
  * edi: kernel thread arg
  */
 ENTRY(ret_from_fork)
-	call	schedule_tail_wrapper
+	FRAME_BEGIN		/* help unwinder find end of stack */
+
+	/*
+	 * schedule_tail() is asmlinkage so we have to put its 'prev' argument
+	 * on the stack.
+	 */
+	pushl	%eax
+	call	schedule_tail
+	popl	%eax
 
 	testl	%ebx, %ebx
 	jnz	1f		/* kernel threads are uncommon */
 
 2:
 	/* When we fork, we trace the syscall return in the child, too. */
-	movl    %esp, %eax
+	leal	FRAME_OFFSET(%esp), %eax
 	call    syscall_return_slowpath
+	FRAME_END
 	jmp     restore_all
 
 	/* kernel thread */
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 5b21970..044d18e 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -36,6 +36,7 @@
 #include <asm/smap.h>
 #include <asm/pgtable_types.h>
 #include <asm/export.h>
+#include <asm/frame.h>
 #include <linux/err.h>
 
 .code64
@@ -408,17 +409,19 @@ END(__switch_to_asm)
  * r12: kernel thread arg
  */
 ENTRY(ret_from_fork)
+	FRAME_BEGIN			/* help unwinder find end of stack */
 	movq	%rax, %rdi
-	call	schedule_tail			/* rdi: 'prev' task parameter */
+	call	schedule_tail		/* rdi: 'prev' task parameter */
 
-	testq	%rbx, %rbx			/* from kernel_thread? */
-	jnz	1f				/* kernel threads are uncommon */
+	testq	%rbx, %rbx		/* from kernel_thread? */
+	jnz	1f			/* kernel threads are uncommon */
 
 2:
-	movq	%rsp, %rdi
+	leaq	FRAME_OFFSET(%rsp),%rdi	/* pt_regs pointer */
 	call	syscall_return_slowpath	/* returns with IRQs disabled */
 	TRACE_IRQS_ON			/* user mode is traced as IRQS on */
 	SWAPGS
+	FRAME_END
 	jmp	restore_regs_and_iret
 
 1:

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-01-12 10:14 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-09 18:00 [PATCH 0/4] x86: unwinder/entry fixes Josh Poimboeuf
2017-01-09 18:00 ` [PATCH 1/4] x86/unwind: silence warnings for non-current tasks Josh Poimboeuf
2017-01-12 10:04   ` [tip:x86/urgent] x86/unwind: Silence " tip-bot for Josh Poimboeuf
2017-01-09 18:00 ` [PATCH 2/4] x86/unwind: disable KASAN checks " Josh Poimboeuf
2017-01-12 10:04   ` [tip:x86/urgent] x86/unwind: Disable " tip-bot for Josh Poimboeuf
2017-01-09 18:00 ` [PATCH 3/4] x86/unwind: include __schedule() in stack traces Josh Poimboeuf
2017-01-10 10:14   ` Miroslav Benes
2017-01-10 17:28     ` Josh Poimboeuf
2017-01-10 20:02       ` Miroslav Benes
2017-01-12 10:05   ` [tip:x86/urgent] x86/unwind: Include " tip-bot for Josh Poimboeuf
2017-01-09 18:00 ` [PATCH 4/4] x86/entry: fix the end of the stack for newly forked tasks Josh Poimboeuf
2017-01-12 10:05   ` [tip:x86/urgent] x86/entry: Fix " tip-bot for Josh Poimboeuf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).