From: Robert Richter <robert.richter@amd.com>
To: Ingo Molnar <mingo@kernel.org>, "H. Peter Anvin" <hpa@linux.intel.com>
Cc: wyang1 <Wei.Yang@windriver.com>,
Peter Zijlstra <peterz@infradead.org>,
Steven Rostedt <rostedt@goodmis.org>,
<linux-kernel@vger.kernel.org>,
<oprofile-list@lists.sourceforge.net>
Subject: Re: [PATCH -v2] x86, 32-bit: Fix invalid stack address while in softirq
Date: Mon, 1 Oct 2012 14:21:11 +0200 [thread overview]
Message-ID: <20121001122111.GN8285@erda.amd.com> (raw)
In-Reply-To: <20120912135059.GZ8285@erda.amd.com>
Ingo, Peter,
any opinions on this patch?
Thanks,
-Robert
On 12.09.12 15:50:59, Robert Richter wrote:
> Updated version below. Changes are:
>
> * add comments to kernel_stack_pointer()
> * always return a valid stack address by falling back to the address
> of regs
>
> -Robert
>
>
> From 0114d0e2ff6ce3f6015fd991541a45261f14eab1 Mon Sep 17 00:00:00 2001
> From: Robert Richter <robert.richter@amd.com>
> Date: Mon, 3 Sep 2012 20:54:48 +0200
> Subject: [PATCH] x86, 32-bit: Fix invalid stack address while in softirq
>
> In 32 bit the stack address provided by kernel_stack_pointer() may
> point to an invalid range causing NULL pointer access or page faults
> while in NMI (see trace below). This happens if called in softirq
> context and if the stack is empty. The address at ®s->sp is then
> out of range.
>
> Fixing this by checking if regs and ®s->sp are in the same stack
> context. Otherwise return the previous stack pointer stored in struct
> thread_info. If that address is invalid too, return address of regs.
>
> BUG: unable to handle kernel NULL pointer dereference at 0000000a
> IP: [<c1004237>] print_context_stack+0x6e/0x8d
> *pde = 00000000
> Oops: 0000 [#1] SMP
> Modules linked in:
> Pid: 4434, comm: perl Not tainted 3.6.0-rc3-oprofile-i386-standard-g4411a05 #4 Hewlett-Packard HP xw9400 Workstation/0A1Ch
> EIP: 0060:[<c1004237>] EFLAGS: 00010093 CPU: 0
> EIP is at print_context_stack+0x6e/0x8d
> EAX: ffffe000 EBX: 0000000a ECX: f4435f94 EDX: 0000000a
> ESI: f4435f94 EDI: f4435f94 EBP: f5409ec0 ESP: f5409ea0
> DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
> CR0: 8005003b CR2: 0000000a CR3: 34ac9000 CR4: 000007d0
> DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
> DR6: ffff0ff0 DR7: 00000400
> Process perl (pid: 4434, ti=f5408000 task=f5637850 task.ti=f4434000)
> Stack:
> 000003e8 ffffe000 00001ffc f4e39b00 00000000 0000000a f4435f94 c155198c
> f5409ef0 c1003723 c155198c f5409f04 00000000 f5409edc 00000000 00000000
> f5409ee8 f4435f94 f5409fc4 00000001 f5409f1c c12dce1c 00000000 c155198c
> Call Trace:
> [<c1003723>] dump_trace+0x7b/0xa1
> [<c12dce1c>] x86_backtrace+0x40/0x88
> [<c12db712>] ? oprofile_add_sample+0x56/0x84
> [<c12db731>] oprofile_add_sample+0x75/0x84
> [<c12ddb5b>] op_amd_check_ctrs+0x46/0x260
> [<c12dd40d>] profile_exceptions_notify+0x23/0x4c
> [<c1395034>] nmi_handle+0x31/0x4a
> [<c1029dc5>] ? ftrace_define_fields_irq_handler_entry+0x45/0x45
> [<c13950ed>] do_nmi+0xa0/0x2ff
> [<c1029dc5>] ? ftrace_define_fields_irq_handler_entry+0x45/0x45
> [<c13949e5>] nmi_stack_correct+0x28/0x2d
> [<c1029dc5>] ? ftrace_define_fields_irq_handler_entry+0x45/0x45
> [<c1003603>] ? do_softirq+0x4b/0x7f
> <IRQ>
> [<c102a06f>] irq_exit+0x35/0x5b
> [<c1018f56>] smp_apic_timer_interrupt+0x6c/0x7a
> [<c1394746>] apic_timer_interrupt+0x2a/0x30
> Code: 89 fe eb 08 31 c9 8b 45 0c ff 55 ec 83 c3 04 83 7d 10 00 74 0c 3b 5d 10 73 26 3b 5d e4 73 0c eb 1f 3b 5d f0 76 1a 3b 5d e8 73 15 <8b> 13 89 d0 89 55 e0 e8 ad 42 03 00 85 c0 8b 55 e0 75 a6 eb cc
> EIP: [<c1004237>] print_context_stack+0x6e/0x8d SS:ESP 0068:f5409ea0
> CR2: 000000000000000a
> ---[ end trace 62afee3481b00012 ]---
> Kernel panic - not syncing: Fatal exception in interrupt
>
> V2:
> * add comments to kernel_stack_pointer()
> * always return a valid stack address by falling back to the address
> of regs
>
> Reported-by: Yang Wei <wei.yang@windriver.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Robert Richter <robert.richter@amd.com>
> ---
> arch/x86/include/asm/ptrace.h | 15 ++++-----------
> arch/x86/kernel/ptrace.c | 28 ++++++++++++++++++++++++++++
> 2 files changed, 32 insertions(+), 11 deletions(-)
>
> diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
> index dcfde52..19f16eb 100644
> --- a/arch/x86/include/asm/ptrace.h
> +++ b/arch/x86/include/asm/ptrace.h
> @@ -205,21 +205,14 @@ static inline bool user_64bit_mode(struct pt_regs *regs)
> }
> #endif
>
> -/*
> - * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
> - * when it traps. The previous stack will be directly underneath the saved
> - * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'.
> - *
> - * This is valid only for kernel mode traps.
> - */
> -static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
> -{
> #ifdef CONFIG_X86_32
> - return (unsigned long)(®s->sp);
> +extern unsigned long kernel_stack_pointer(struct pt_regs *regs);
> #else
> +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
> +{
> return regs->sp;
> -#endif
> }
> +#endif
>
> #define GET_IP(regs) ((regs)->ip)
> #define GET_FP(regs) ((regs)->bp)
> diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
> index c4c6a5c..947cf90 100644
> --- a/arch/x86/kernel/ptrace.c
> +++ b/arch/x86/kernel/ptrace.c
> @@ -165,6 +165,34 @@ static inline bool invalid_selector(u16 value)
>
> #define FLAG_MASK FLAG_MASK_32
>
> +/*
> + * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
> + * when it traps. The previous stack will be directly underneath the saved
> + * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'.
> + *
> + * Now, if the stack is empty, '®s->sp' is out of range. In this
> + * case we try to take the previous stack. To always return a non-null
> + * stack pointer we fall back to regs as stack if no previous stack
> + * exists.
> + *
> + * This is valid only for kernel mode traps.
> + */
> +unsigned long kernel_stack_pointer(struct pt_regs *regs)
> +{
> + unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1);
> + unsigned long sp = (unsigned long)®s->sp;
> + struct thread_info *tinfo;
> +
> + if (context == (sp & ~(THREAD_SIZE - 1)))
> + return sp;
> +
> + tinfo = (struct thread_info *)context;
> + if (tinfo->previous_esp)
> + return tinfo->previous_esp;
> +
> + return (unsigned long)regs;
> +}
> +
> static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno)
> {
> BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0);
> --
> 1.7.8.6
>
>
>
> --
> Advanced Micro Devices, Inc.
> Operating System Research Center
--
Advanced Micro Devices, Inc.
Operating System Research Center
next prev parent reply other threads:[~2012-10-01 12:21 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-27 1:32 [PATCH 1/1] x86/oprofile: Fix the calltrace upon profiling some specified events with oprofile Wei.Yang
2012-08-28 9:17 ` Robert Richter
2012-09-03 5:28 ` wyang1
2012-09-04 10:24 ` Robert Richter
2012-09-06 1:30 ` wyang1
2012-09-06 10:04 ` [PATCH] x86, 32-bit: Fix invalid stack address while in softirq Robert Richter
2012-09-06 13:14 ` Steven Rostedt
2012-09-06 15:02 ` Robert Richter
2012-09-06 15:14 ` Steven Rostedt
2012-09-06 15:34 ` Robert Richter
2012-09-06 15:36 ` Robert Richter
2012-09-06 15:54 ` Steven Rostedt
2012-09-07 5:21 ` wyang1
2012-09-12 13:50 ` [PATCH -v2] " Robert Richter
2012-09-12 14:04 ` Steven Rostedt
2012-10-01 12:21 ` Robert Richter [this message]
2012-11-01 21:34 ` [tip:x86/urgent] x86-32: " tip-bot for Robert Richter
2012-11-13 15:17 ` Ingo Molnar
2012-11-13 15:56 ` Robert Richter
2012-11-15 21:53 ` tip-bot for Robert Richter
2012-11-21 7:34 ` tip-bot for Robert Richter
2012-11-21 7:35 ` [tip:x86/urgent] x86-32: Export kernel_stack_pointer() for modules tip-bot for H. Peter Anvin
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=20121001122111.GN8285@erda.amd.com \
--to=robert.richter@amd.com \
--cc=Wei.Yang@windriver.com \
--cc=hpa@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=oprofile-list@lists.sourceforge.net \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
/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.