* [PATCH] use canary at end of stack to indicate overruns at oops time
@ 2008-04-22 3:44 Eric Sandeen
2008-04-22 4:20 ` Arjan van de Ven
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Eric Sandeen @ 2008-04-22 3:44 UTC (permalink / raw)
To: linux-kernel Mailing List; +Cc: Arjan van de Ven, Andrew Morton
Use a canary at the end of the stack to clearly indicate
at oops time whether the stack has ever overflowed.
This is a very simple implementation with a couple of
drawbacks:
1) a thread may legitimately use exactly up to the last
word on the stack
-- but the chances of doing this and then oopsing later seem slim
2) it's possible that the stack usage isn't dense enough
that the canary location could get skipped over
-- but the worst that happens is that we don't flag the overrun
With the code in place, an intentionally-bloated stack oops does:
BUG: unable to handle kernel paging request at ffff8103f84cc680
IP: [<ffffffff810253df>] update_curr+0x9a/0xa8
PGD 8063 PUD 0
Thread overran stack or stack corrupted
Oops: 0000 [1] SMP
CPU 0
...
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
Index: linux-2.6.25/arch/x86/mm/fault.c
===================================================================
--- linux-2.6.25.orig/arch/x86/mm/fault.c 2008-04-20 22:30:36.000000000 -0500
+++ linux-2.6.25/arch/x86/mm/fault.c 2008-04-21 16:58:18.913885442 -0500
@@ -25,6 +25,7 @@
#include <linux/kprobes.h>
#include <linux/uaccess.h>
#include <linux/kdebug.h>
+#include <linux/magic.h>
#include <asm/system.h>
#include <asm/desc.h>
@@ -581,6 +582,8 @@ void __kprobes do_page_fault(struct pt_r
unsigned long address;
int write, si_code;
int fault;
+ unsigned long *stackend;
+
#ifdef CONFIG_X86_64
unsigned long flags;
#endif
@@ -850,6 +853,10 @@ no_context:
show_fault_oops(regs, error_code, address);
+ stackend = end_of_stack(tsk);
+ if (*stackend != STACK_END_MAGIC)
+ printk(KERN_ALERT "Thread overran stack or stack corrupted\n");
+
tsk->thread.cr2 = address;
tsk->thread.trap_no = 14;
tsk->thread.error_code = error_code;
Index: linux-2.6.25/include/linux/magic.h
===================================================================
--- linux-2.6.25.orig/include/linux/magic.h 2008-01-24 16:58:37.000000000 -0600
+++ linux-2.6.25/include/linux/magic.h 2008-04-21 16:53:47.838406992 -0500
@@ -42,4 +42,5 @@
#define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
#define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA
+#define STACK_END_MAGIC 0x57AC6E9D
#endif /* __LINUX_MAGIC_H__ */
Index: linux-2.6.25/kernel/fork.c
===================================================================
--- linux-2.6.25.orig/kernel/fork.c 2008-04-21 16:49:49.000000000 -0500
+++ linux-2.6.25/kernel/fork.c 2008-04-21 16:54:22.039406916 -0500
@@ -53,6 +53,7 @@
#include <linux/tty.h>
#include <linux/proc_fs.h>
#include <linux/blkdev.h>
+#include <linux/magic.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -167,6 +168,8 @@ static struct task_struct *dup_task_stru
{
struct task_struct *tsk;
struct thread_info *ti;
+ unsigned long *stackend;
+
int err;
prepare_to_copy(orig);
@@ -192,6 +195,8 @@ static struct task_struct *dup_task_stru
}
setup_thread_stack(tsk, orig);
+ stackend = end_of_stack(tsk);
+ *stackend = STACK_END_MAGIC; /* for overflow detection */
#ifdef CONFIG_CC_STACKPROTECTOR
tsk->stack_canary = get_random_int();
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] use canary at end of stack to indicate overruns at oops time
2008-04-22 3:44 [PATCH] use canary at end of stack to indicate overruns at oops time Eric Sandeen
@ 2008-04-22 4:20 ` Arjan van de Ven
2008-04-22 8:44 ` Ingo Molnar
2008-04-22 21:38 ` [PATCH V2] use canary at end of stack to indicate overruns at oops time Eric Sandeen
2 siblings, 0 replies; 12+ messages in thread
From: Arjan van de Ven @ 2008-04-22 4:20 UTC (permalink / raw)
To: Eric Sandeen; +Cc: linux-kernel Mailing List, Andrew Morton
On Mon, 21 Apr 2008 22:44:39 -0500
Eric Sandeen <sandeen@redhat.com> wrote:
> Use a canary at the end of the stack to clearly indicate
> at oops time whether the stack has ever overflowed.
>
> This is a very simple implementation with a couple of
> drawbacks:
>
> 1) a thread may legitimately use exactly up to the last
> word on the stack
>
> -- but the chances of doing this and then oopsing later seem slim
>
> 2) it's possible that the stack usage isn't dense enough
> that the canary location could get skipped over
>
> -- but the worst that happens is that we don't flag the overrun
>
> With the code in place, an intentionally-bloated stack oops does:
>
> BUG: unable to handle kernel paging request at ffff8103f84cc680
> IP: [<ffffffff810253df>] update_curr+0x9a/0xa8
> PGD 8063 PUD 0
> Thread overran stack or stack corrupted
> Oops: 0000 [1] SMP
> CPU 0
I like this but I wonder if it's useful to do this for the irq stacks too;
either way
Acked-by: Arjan van de Ven <arjan@linux.intel.com>
(I'll also add detection of your printk to the kerneloops.org website)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] use canary at end of stack to indicate overruns at oops time
2008-04-22 3:44 [PATCH] use canary at end of stack to indicate overruns at oops time Eric Sandeen
2008-04-22 4:20 ` Arjan van de Ven
@ 2008-04-22 8:44 ` Ingo Molnar
2008-04-22 16:44 ` Eric Sandeen
2008-04-22 21:38 ` [PATCH V2] use canary at end of stack to indicate overruns at oops time Eric Sandeen
2 siblings, 1 reply; 12+ messages in thread
From: Ingo Molnar @ 2008-04-22 8:44 UTC (permalink / raw)
To: Eric Sandeen; +Cc: linux-kernel Mailing List, Arjan van de Ven, Andrew Morton
* Eric Sandeen <sandeen@redhat.com> wrote:
> Use a canary at the end of the stack to clearly indicate at oops time
> whether the stack has ever overflowed.
>
> This is a very simple implementation with a couple of drawbacks:
>
> 1) a thread may legitimately use exactly up to the last
> word on the stack
>
> -- but the chances of doing this and then oopsing later seem slim
even that narrow case is a bug - an NMI might arrive at exactly that
point and overflow the stack for real.
> 2) it's possible that the stack usage isn't dense enough
> that the canary location could get skipped over
>
> -- but the worst that happens is that we don't flag the overrun
yeah.
> With the code in place, an intentionally-bloated stack oops does:
>
> BUG: unable to handle kernel paging request at ffff8103f84cc680
> IP: [<ffffffff810253df>] update_curr+0x9a/0xa8
> PGD 8063 PUD 0
> Thread overran stack or stack corrupted
> Oops: 0000 [1] SMP
> CPU 0
> ...
excellent. I've queued this up, it's definitely an improvement in
debuggability.
we used to have something comparable in ancient kernels (it was called
the stack red zone IIRC) - but it was not printed in oopses and we lost
the feature somewhere anyway.
Ingo
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] use canary at end of stack to indicate overruns at oops time
2008-04-22 8:44 ` Ingo Molnar
@ 2008-04-22 16:44 ` Eric Sandeen
2008-04-22 17:18 ` [PATCH] Fix max-stack calculators to skip canary Eric Sandeen
0 siblings, 1 reply; 12+ messages in thread
From: Eric Sandeen @ 2008-04-22 16:44 UTC (permalink / raw)
To: Ingo Molnar
Cc: Eric Sandeen, linux-kernel Mailing List, Arjan van de Ven,
Andrew Morton
Ingo Molnar wrote:
> * Eric Sandeen <sandeen@redhat.com> wrote:
>> With the code in place, an intentionally-bloated stack oops does:
>>
>> BUG: unable to handle kernel paging request at ffff8103f84cc680
>> IP: [<ffffffff810253df>] update_curr+0x9a/0xa8
>> PGD 8063 PUD 0
>> Thread overran stack or stack corrupted
>> Oops: 0000 [1] SMP
>> CPU 0
>> ...
>
> excellent. I've queued this up, it's definitely an improvement in
> debuggability.
Crud, just realized this probably doesn't play well with
CONFIG_DEBUG_STACK_USAGE. I think it will need something like:
Index: linux-2.6.25-rc7/kernel/exit.c
===================================================================
--- linux-2.6.25-rc7.orig/kernel/exit.c 2008-04-20 22:34:16.000000000 -0500
+++ linux-2.6.25-rc7/kernel/exit.c 2008-04-22 11:38:05.769412824 -0500
@@ -826,6 +826,8 @@ static void check_stack_usage(void)
unsigned long *n = end_of_stack(current);
unsigned long free;
+ n++; /* skip over canary at end */
+
while (*n == 0)
n++;
free = (unsigned long)n - (unsigned long)end_of_stack(current);
Testing now... want me to resend the whole patch, Ingo, or you want to
just fix it up? (I'll follow up with the testing results)
Thanks,
-Eric
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] Fix max-stack calculators to skip canary
2008-04-22 16:44 ` Eric Sandeen
@ 2008-04-22 17:18 ` Eric Sandeen
2008-04-22 17:33 ` Joe Perches
2008-04-28 17:28 ` Ingo Molnar
0 siblings, 2 replies; 12+ messages in thread
From: Eric Sandeen @ 2008-04-22 17:18 UTC (permalink / raw)
To: Ingo Molnar
Cc: Eric Sandeen, linux-kernel Mailing List, Arjan van de Ven,
Andrew Morton
With the canary on the end of the stack, anything which
looks for 0 to mean unused when calculating max stack
excursions must skip over this non-zero magic number.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
Index: linux-2.6.25/kernel/exit.c
===================================================================
--- linux-2.6.25.orig/kernel/exit.c 2008-04-20 22:34:16.000000000 -0500
+++ linux-2.6.25/kernel/exit.c 2008-04-22 11:38:05.769412824 -0500
@@ -826,6 +826,8 @@ static void check_stack_usage(void)
unsigned long *n = end_of_stack(current);
unsigned long free;
+ n++; /* skip over canary at end */
+
while (*n == 0)
n++;
free = (unsigned long)n - (unsigned long)end_of_stack(current);
Index: linux-2.6.25/kernel/sched.c
===================================================================
--- linux-2.6.25.orig/kernel/sched.c 2008-04-20 22:34:19.000000000 -0500
+++ linux-2.6.25/kernel/sched.c 2008-04-22 11:48:06.975407495 -0500
@@ -5190,6 +5190,8 @@ void sched_show_task(struct task_struct
#ifdef CONFIG_DEBUG_STACK_USAGE
{
unsigned long *n = end_of_stack(p);
+
+ n++; /* skip over canary at end */
while (!*n)
n++;
free = (unsigned long)n - (unsigned long)end_of_stack(p);
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Fix max-stack calculators to skip canary
2008-04-22 17:18 ` [PATCH] Fix max-stack calculators to skip canary Eric Sandeen
@ 2008-04-22 17:33 ` Joe Perches
2008-04-22 18:09 ` Eric Sandeen
2008-04-28 17:28 ` Ingo Molnar
1 sibling, 1 reply; 12+ messages in thread
From: Joe Perches @ 2008-04-22 17:33 UTC (permalink / raw)
To: Eric Sandeen
Cc: Ingo Molnar, linux-kernel Mailing List, Arjan van de Ven,
Andrew Morton
On Tue, 2008-04-22 at 12:18 -0500, Eric Sandeen wrote:
> Index: linux-2.6.25/kernel/exit.c
> ===================================================================
> --- linux-2.6.25.orig/kernel/exit.c 2008-04-20 22:34:16.000000000 -0500
> +++ linux-2.6.25/kernel/exit.c 2008-04-22 11:38:05.769412824 -0500
> @@ -826,6 +826,8 @@ static void check_stack_usage(void)
> unsigned long *n = end_of_stack(current);
> unsigned long free;
>
> + n++; /* skip over canary at end */
> +
> while (*n == 0)
> n++;
> free = (unsigned long)n - (unsigned long)end_of_stack(current);
> Index: linux-2.6.25/kernel/sched.c
> ===================================================================
> --- linux-2.6.25.orig/kernel/sched.c 2008-04-20 22:34:19.000000000 -0500
> +++ linux-2.6.25/kernel/sched.c 2008-04-22 11:48:06.975407495 -0500
> @@ -5190,6 +5190,8 @@ void sched_show_task(struct task_struct
> #ifdef CONFIG_DEBUG_STACK_USAGE
> {
> unsigned long *n = end_of_stack(p);
> +
> + n++; /* skip over canary at end */
> while (!*n)
> n++;
> free = (unsigned long)n - (unsigned long)end_of_stack(p);
>
Wouldn't it be better to have exactly the same code?
How about using a statement expression macro?
#define DEBUG_STACK_FREE(process) \
({ \
unsigned long *n = end_of_stack(process); \
do { /* Skip over canary */\
n++; \
} while (!*n); \
(unsigned long)n - (unsigned long)end_of_stack(process); \
})
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Fix max-stack calculators to skip canary
2008-04-22 17:33 ` Joe Perches
@ 2008-04-22 18:09 ` Eric Sandeen
0 siblings, 0 replies; 12+ messages in thread
From: Eric Sandeen @ 2008-04-22 18:09 UTC (permalink / raw)
To: Joe Perches
Cc: Ingo Molnar, linux-kernel Mailing List, Arjan van de Ven,
Andrew Morton
Joe Perches wrote:
> Wouldn't it be better to have exactly the same code?
> How about using a statement expression macro?
>
> #define DEBUG_STACK_FREE(process) \
> ({ \
> unsigned long *n = end_of_stack(process); \
> do { /* Skip over canary */\
> n++; \
> } while (!*n); \
> (unsigned long)n - (unsigned long)end_of_stack(process); \
> })
>
That'd probably be good although I don't think we like macros anymore :)
-Eric
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH V2] use canary at end of stack to indicate overruns at oops time
2008-04-22 3:44 [PATCH] use canary at end of stack to indicate overruns at oops time Eric Sandeen
2008-04-22 4:20 ` Arjan van de Ven
2008-04-22 8:44 ` Ingo Molnar
@ 2008-04-22 21:38 ` Eric Sandeen
2008-04-22 22:14 ` Harvey Harrison
2008-04-28 17:31 ` Ingo Molnar
2 siblings, 2 replies; 12+ messages in thread
From: Eric Sandeen @ 2008-04-22 21:38 UTC (permalink / raw)
To: Eric Sandeen
Cc: linux-kernel Mailing List, Arjan van de Ven, Andrew Morton,
Ingo Molnar, Joe Perches
(Updated with a common max-stack-used checker that knows about
the canary, as suggested by Joe Perches)
Use a canary at the end of the stack to clearly indicate
at oops time whether the stack has ever overflowed.
This is a very simple implementation with a couple of
drawbacks:
1) a thread may legitimately use exactly up to the last
word on the stack
-- but the chances of doing this and then oopsing later seem slim
2) it's possible that the stack usage isn't dense enough
that the canary location could get skipped over
-- but the worst that happens is that we don't flag the overrun
-- though this happens fairly often in my testing :(
With the code in place, an intentionally-bloated stack oops might
do:
BUG: unable to handle kernel paging request at ffff8103f84cc680
IP: [<ffffffff810253df>] update_curr+0x9a/0xa8
PGD 8063 PUD 0
Thread overran stack or stack corrupted
Oops: 0000 [1] SMP
CPU 0
...
... unless the stack overrun is so bad that it corrupts some other
thread.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
Index: linux-2.6.25/arch/x86/mm/fault.c
===================================================================
--- linux-2.6.25.orig/arch/x86/mm/fault.c
+++ linux-2.6.25/arch/x86/mm/fault.c
@@ -25,6 +25,7 @@
#include <linux/kprobes.h>
#include <linux/uaccess.h>
#include <linux/kdebug.h>
+#include <linux/magic.h>
#include <asm/system.h>
#include <asm/desc.h>
@@ -581,6 +582,8 @@ void __kprobes do_page_fault(struct pt_r
unsigned long address;
int write, si_code;
int fault;
+ unsigned long *stackend;
+
#ifdef CONFIG_X86_64
unsigned long flags;
#endif
@@ -850,6 +853,10 @@ no_context:
show_fault_oops(regs, error_code, address);
+ stackend = end_of_stack(tsk);
+ if (*stackend != STACK_END_MAGIC)
+ printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
+
tsk->thread.cr2 = address;
tsk->thread.trap_no = 14;
tsk->thread.error_code = error_code;
Index: linux-2.6.25/include/linux/magic.h
===================================================================
--- linux-2.6.25.orig/include/linux/magic.h
+++ linux-2.6.25/include/linux/magic.h
@@ -42,4 +42,5 @@
#define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
#define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA
+#define STACK_END_MAGIC 0x57AC6E9D
#endif /* __LINUX_MAGIC_H__ */
Index: linux-2.6.25/kernel/fork.c
===================================================================
--- linux-2.6.25.orig/kernel/fork.c
+++ linux-2.6.25/kernel/fork.c
@@ -53,6 +53,7 @@
#include <linux/tty.h>
#include <linux/proc_fs.h>
#include <linux/blkdev.h>
+#include <linux/magic.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -167,6 +168,8 @@ static struct task_struct *dup_task_stru
{
struct task_struct *tsk;
struct thread_info *ti;
+ unsigned long *stackend;
+
int err;
prepare_to_copy(orig);
@@ -192,6 +195,8 @@ static struct task_struct *dup_task_stru
}
setup_thread_stack(tsk, orig);
+ stackend = end_of_stack(tsk);
+ *stackend = STACK_END_MAGIC; /* for overflow detection */
#ifdef CONFIG_CC_STACKPROTECTOR
tsk->stack_canary = get_random_int();
Index: linux-2.6.25/kernel/exit.c
===================================================================
--- linux-2.6.25.orig/kernel/exit.c
+++ linux-2.6.25/kernel/exit.c
@@ -823,12 +823,9 @@ static void check_stack_usage(void)
{
static DEFINE_SPINLOCK(low_water_lock);
static int lowest_to_date = THREAD_SIZE;
- unsigned long *n = end_of_stack(current);
unsigned long free;
- while (*n == 0)
- n++;
- free = (unsigned long)n - (unsigned long)end_of_stack(current);
+ free = stack_not_used(current);
if (free >= lowest_to_date)
return;
Index: linux-2.6.25/kernel/sched.c
===================================================================
--- linux-2.6.25.orig/kernel/sched.c
+++ linux-2.6.25/kernel/sched.c
@@ -5188,12 +5188,7 @@ void sched_show_task(struct task_struct
printk(KERN_CONT " %016lx ", thread_saved_pc(p));
#endif
#ifdef CONFIG_DEBUG_STACK_USAGE
- {
- unsigned long *n = end_of_stack(p);
- while (!*n)
- n++;
- free = (unsigned long)n - (unsigned long)end_of_stack(p);
- }
+ free = stack_not_used(p);
#endif
printk(KERN_CONT "%5lu %5d %6d\n", free,
task_pid_nr(p), task_pid_nr(p->real_parent));
Index: linux-2.6.25/include/linux/sched.h
===================================================================
--- linux-2.6.25.orig/include/linux/sched.h
+++ linux-2.6.25/include/linux/sched.h
@@ -1893,6 +1893,19 @@ static inline unsigned long *end_of_stac
#endif
+#ifdef CONFIG_DEBUG_STACK_USAGE
+static inline unsigned long stack_not_used(struct task_struct *p)
+{
+ unsigned long *n = end_of_stack(p);
+
+ do { /* Skip over canary */
+ n++;
+ } while (!*n);
+
+ return (unsigned long)n - (unsigned long)end_of_stack(p);
+}
+#endif
+
/* set thread flags in other task's structures
* - see asm/thread_info.h for TIF_xxxx flags available
*/
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH V2] use canary at end of stack to indicate overruns at oops time
2008-04-22 21:38 ` [PATCH V2] use canary at end of stack to indicate overruns at oops time Eric Sandeen
@ 2008-04-22 22:14 ` Harvey Harrison
2008-04-22 22:28 ` Eric Sandeen
2008-04-28 17:31 ` Ingo Molnar
1 sibling, 1 reply; 12+ messages in thread
From: Harvey Harrison @ 2008-04-22 22:14 UTC (permalink / raw)
To: Eric Sandeen
Cc: Eric Sandeen, linux-kernel Mailing List, Arjan van de Ven,
Andrew Morton, Ingo Molnar, Joe Perches
On Tue, 2008-04-22 at 16:38 -0500, Eric Sandeen wrote:
> ... unless the stack overrun is so bad that it corrupts some other
> thread.
>
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
> ---
>
> Index: linux-2.6.25/arch/x86/mm/fault.c
> ===================================================================
> --- linux-2.6.25.orig/arch/x86/mm/fault.c
> +++ linux-2.6.25/arch/x86/mm/fault.c
> @@ -25,6 +25,7 @@
> #include <linux/kprobes.h>
> #include <linux/uaccess.h>
> #include <linux/kdebug.h>
> +#include <linux/magic.h>
>
> #include <asm/system.h>
> #include <asm/desc.h>
> @@ -581,6 +582,8 @@ void __kprobes do_page_fault(struct pt_r
> unsigned long address;
> int write, si_code;
> int fault;
> + unsigned long *stackend;
> +
> #ifdef CONFIG_X86_64
> unsigned long flags;
> #endif
> @@ -850,6 +853,10 @@ no_context:
>
> show_fault_oops(regs, error_code, address);
>
> + stackend = end_of_stack(tsk);
> + if (*stackend != STACK_END_MAGIC)
> + printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
> +
> tsk->thread.cr2 = address;
> tsk->thread.trap_no = 14;
> tsk->thread.error_code = error_code;
> Index: linux-2.6.25/include/linux/magic.h
> ===================================================================
> --- linux-2.6.25.orig/include/linux/magic.h
> +++ linux-2.6.25/include/linux/magic.h
> @@ -42,4 +42,5 @@
> #define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
> #define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA
>
> +#define STACK_END_MAGIC 0x57AC6E9D
> #endif /* __LINUX_MAGIC_H__ */
> Index: linux-2.6.25/kernel/fork.c
> ===================================================================
> --- linux-2.6.25.orig/kernel/fork.c
> +++ linux-2.6.25/kernel/fork.c
> @@ -53,6 +53,7 @@
> #include <linux/tty.h>
> #include <linux/proc_fs.h>
> #include <linux/blkdev.h>
> +#include <linux/magic.h>
>
> #include <asm/pgtable.h>
> #include <asm/pgalloc.h>
> @@ -167,6 +168,8 @@ static struct task_struct *dup_task_stru
> {
> struct task_struct *tsk;
> struct thread_info *ti;
> + unsigned long *stackend;
> +
> int err;
>
> prepare_to_copy(orig);
> @@ -192,6 +195,8 @@ static struct task_struct *dup_task_stru
> }
>
> setup_thread_stack(tsk, orig);
> + stackend = end_of_stack(tsk);
> + *stackend = STACK_END_MAGIC; /* for overflow detection */
>
> #ifdef CONFIG_CC_STACKPROTECTOR
> tsk->stack_canary = get_random_int();
> Index: linux-2.6.25/kernel/exit.c
> ===================================================================
> --- linux-2.6.25.orig/kernel/exit.c
> +++ linux-2.6.25/kernel/exit.c
> @@ -823,12 +823,9 @@ static void check_stack_usage(void)
> {
> static DEFINE_SPINLOCK(low_water_lock);
> static int lowest_to_date = THREAD_SIZE;
> - unsigned long *n = end_of_stack(current);
> unsigned long free;
>
> - while (*n == 0)
> - n++;
> - free = (unsigned long)n - (unsigned long)end_of_stack(current);
> + free = stack_not_used(current);
>
> if (free >= lowest_to_date)
> return;
> Index: linux-2.6.25/kernel/sched.c
> ===================================================================
> --- linux-2.6.25.orig/kernel/sched.c
> +++ linux-2.6.25/kernel/sched.c
> @@ -5188,12 +5188,7 @@ void sched_show_task(struct task_struct
> printk(KERN_CONT " %016lx ", thread_saved_pc(p));
> #endif
> #ifdef CONFIG_DEBUG_STACK_USAGE
> - {
> - unsigned long *n = end_of_stack(p);
> - while (!*n)
> - n++;
> - free = (unsigned long)n - (unsigned long)end_of_stack(p);
> - }
> + free = stack_not_used(p);
> #endif
Maybe remove the #ifdef CONFIG_DEBUG_STACK_USAGE block and move it into
stack_not_used...call it debug_stack_not_used.
> printk(KERN_CONT "%5lu %5d %6d\n", free,
> task_pid_nr(p), task_pid_nr(p->real_parent));
> Index: linux-2.6.25/include/linux/sched.h
> ===================================================================
> --- linux-2.6.25.orig/include/linux/sched.h
> +++ linux-2.6.25/include/linux/sched.h
> @@ -1893,6 +1893,19 @@ static inline unsigned long *end_of_stac
>
> #endif
>
> +#ifdef CONFIG_DEBUG_STACK_USAGE
> +static inline unsigned long stack_not_used(struct task_struct *p)
> +{
> + unsigned long *n = end_of_stack(p);
> +
> + do { /* Skip over canary */
> + n++;
> + } while (!*n);
> +
> + return (unsigned long)n - (unsigned long)end_of_stack(p);
> +}
> +#endif
> +
static inline unsigned long debug_stack_not_used(struct task_struct *p)
{
#ifdef CONFIG_DEBUG_STACK_USAGE
unsigned long *n = end_of_stack(p);
do { /* Skip over canary */
n++;
} while (!*n);
return (unsigned long)n - (unsigned long)end_of_stack(p);
#else
return $(large_value)....maybe or just some known value.
#endif
}
Also, do you expect this to ever be used outside of sched.c? Maybe just
leave it as a static function there rather than an inline in the header.
Harvey
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH V2] use canary at end of stack to indicate overruns at oops time
2008-04-22 22:14 ` Harvey Harrison
@ 2008-04-22 22:28 ` Eric Sandeen
0 siblings, 0 replies; 12+ messages in thread
From: Eric Sandeen @ 2008-04-22 22:28 UTC (permalink / raw)
To: Harvey Harrison
Cc: Eric Sandeen, linux-kernel Mailing List, Arjan van de Ven,
Andrew Morton, Ingo Molnar, Joe Perches
Harvey Harrison wrote:
> Also, do you expect this to ever be used outside of sched.c? Maybe just
> leave it as a static function there rather than an inline in the header.
the patch uses it in exit.c....
-Eric
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Fix max-stack calculators to skip canary
2008-04-22 17:18 ` [PATCH] Fix max-stack calculators to skip canary Eric Sandeen
2008-04-22 17:33 ` Joe Perches
@ 2008-04-28 17:28 ` Ingo Molnar
1 sibling, 0 replies; 12+ messages in thread
From: Ingo Molnar @ 2008-04-28 17:28 UTC (permalink / raw)
To: Eric Sandeen
Cc: Eric Sandeen, linux-kernel Mailing List, Arjan van de Ven,
Andrew Morton
* Eric Sandeen <sandeen@sandeen.net> wrote:
> With the canary on the end of the stack, anything which looks for 0 to
> mean unused when calculating max stack excursions must skip over this
> non-zero magic number.
>
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
thanks Eric, applied.
Ingo
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH V2] use canary at end of stack to indicate overruns at oops time
2008-04-22 21:38 ` [PATCH V2] use canary at end of stack to indicate overruns at oops time Eric Sandeen
2008-04-22 22:14 ` Harvey Harrison
@ 2008-04-28 17:31 ` Ingo Molnar
1 sibling, 0 replies; 12+ messages in thread
From: Ingo Molnar @ 2008-04-28 17:31 UTC (permalink / raw)
To: Eric Sandeen
Cc: Eric Sandeen, linux-kernel Mailing List, Arjan van de Ven,
Andrew Morton, Joe Perches
* Eric Sandeen <sandeen@sandeen.net> wrote:
> (Updated with a common max-stack-used checker that knows about the
> canary, as suggested by Joe Perches)
thanks - picked up this updated version.
Ingo
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2008-04-28 17:32 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-22 3:44 [PATCH] use canary at end of stack to indicate overruns at oops time Eric Sandeen
2008-04-22 4:20 ` Arjan van de Ven
2008-04-22 8:44 ` Ingo Molnar
2008-04-22 16:44 ` Eric Sandeen
2008-04-22 17:18 ` [PATCH] Fix max-stack calculators to skip canary Eric Sandeen
2008-04-22 17:33 ` Joe Perches
2008-04-22 18:09 ` Eric Sandeen
2008-04-28 17:28 ` Ingo Molnar
2008-04-22 21:38 ` [PATCH V2] use canary at end of stack to indicate overruns at oops time Eric Sandeen
2008-04-22 22:14 ` Harvey Harrison
2008-04-22 22:28 ` Eric Sandeen
2008-04-28 17:31 ` Ingo Molnar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox