From: "David C. Hansen" <haveblue@us.ibm.com>
To: Linus Torvalds <torvalds@transmeta.COM>
Cc: lkml <linux-kernel@vger.kernel.org>
Subject: [PATCH] (3/3) stack overflow checking for x86
Date: 31 Oct 2002 11:20:52 -0800 [thread overview]
Message-ID: <1036092052.4272.96.camel@nighthawk> (raw)
In-Reply-To: <1036091906.4272.87.camel@nighthawk>
[-- Attachment #1: Type: text/plain, Size: 424 bytes --]
* stack checking (3/3)
- use gcc's profiling features to check for stack overflows upon
entry to functions.
- Warn if the task goes over 4k.
- Panic if the stack gets within 512 bytes of overflowing.
- use kksymoops information, if available
This won't apply cleanly without the irqstack patch, but the conflict is
easy to resolve. It requires the thread_info cleanup.
--
Dave Hansen
haveblue@us.ibm.com
[-- Attachment #2: C-stack_usage_check-2.5.45-4.patch --]
[-- Type: text/plain, Size: 6119 bytes --]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.857.1.1 -> 1.859
# arch/i386/kernel/process.c 1.32.1.1 -> 1.36
# arch/i386/kernel/irq.c 1.23.1.1 -> 1.25
# Makefile 1.326.2.11 -> 1.329
# include/asm-i386/thread_info.h 1.10 -> 1.11
# arch/i386/kernel/entry.S 1.38.1.3 -> 1.46
# arch/i386/Makefile 1.24.2.3 -> 1.27
# arch/i386/boot/compressed/misc.c 1.9 -> 1.10
# arch/i386/kernel/init_task.c 1.6.1.1 -> 1.8
# arch/i386/kernel/i386_ksyms.c 1.36.2.3 -> 1.39
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/10/31 haveblue@elm3b96.(none) 1.859
# Merge elm3b96.(none):/work/dave/bk/linux-2.5-irq-stack
# into elm3b96.(none):/work/dave/bk/linux-2.5-irq-stack+overflow-detect
# --------------------------------------------
#
diff -Nru a/Makefile b/Makefile
--- a/Makefile Thu Oct 31 11:13:28 2002
+++ b/Makefile Thu Oct 31 11:13:28 2002
@@ -168,7 +168,8 @@
CPPFLAGS := -D__KERNEL__ -Iinclude
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
- -fomit-frame-pointer -fno-strict-aliasing -fno-common
+ -fno-strict-aliasing -fno-common
+
AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
export VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \
@@ -254,6 +255,10 @@
ifdef CONFIG_MODULES
export EXPORT_FLAGS := -DEXPORT_SYMTAB
+endif
+
+ifneq ($(CONFIG_FRAME_POINTER),y)
+CFLAGS += -fomit-frame-pointer
endif
#
diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile
--- a/arch/i386/Makefile Thu Oct 31 11:13:28 2002
+++ b/arch/i386/Makefile Thu Oct 31 11:13:28 2002
@@ -51,6 +51,10 @@
MACHINE := mach-generic
endif
+ifdef CONFIG_X86_STACK_CHECK
+CFLAGS += -p
+endif
+
HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
libs-y += arch/i386/lib/
diff -Nru a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
--- a/arch/i386/boot/compressed/misc.c Thu Oct 31 11:13:28 2002
+++ b/arch/i386/boot/compressed/misc.c Thu Oct 31 11:13:28 2002
@@ -377,3 +377,7 @@
if (high_loaded) close_output_buffer_if_we_run_high(mv);
return high_loaded;
}
+
+/* We don't actually check for stack overflows this early. */
+__asm__(".globl mcount ; mcount: ret\n");
+
diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S Thu Oct 31 11:13:28 2002
+++ b/arch/i386/kernel/entry.S Thu Oct 31 11:13:28 2002
@@ -519,6 +519,61 @@
pushl $do_spurious_interrupt_bug
jmp error_code
+
+#ifdef CONFIG_X86_STACK_CHECK
+.data
+ .globl stack_overflowed
+stack_overflowed:
+ .long 0
+.text
+
+ENTRY(mcount)
+ push %eax
+ movl $(THREAD_SIZE - 1),%eax
+ andl %esp,%eax
+ cmpl $STACK_WARN,%eax /* more than half the stack is used*/
+ jle 1f
+2:
+ popl %eax
+ ret
+1:
+ lock; btsl $0,stack_overflowed
+ jc 2b
+
+ # switch to overflow stack
+ movl %esp,%eax
+ movl $(stack_overflow_stack + THREAD_SIZE - 4),%esp
+
+ pushf
+ cli
+ pushl %eax
+
+ # push eip then esp of error for stack_overflow_panic
+ pushl 4(%eax)
+ pushl %eax
+
+ # update the task pointer and cpu in the overflow stack's thread_info.
+ GET_THREAD_INFO_WITH_ESP(%eax)
+ movl TI_TASK(%eax),%ebx
+ movl %ebx,stack_overflow_stack+TI_TASK
+ movl TI_CPU(%eax),%ebx
+ movl %ebx,stack_overflow_stack+TI_CPU
+
+ call stack_overflow
+
+ # pop off call arguments
+ addl $8,%esp
+
+ popl %eax
+ popf
+ movl %eax,%esp
+ popl %eax
+ movl $0,stack_overflowed
+ ret
+
+#warning stack check enabled
+#endif
+
.data
ENTRY(sys_call_table)
.long sys_ni_syscall /* 0 - old "setup()" system call*/
diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
--- a/arch/i386/kernel/i386_ksyms.c Thu Oct 31 11:13:28 2002
+++ b/arch/i386/kernel/i386_ksyms.c Thu Oct 31 11:13:28 2002
@@ -211,3 +211,8 @@
EXPORT_SYMBOL(edd);
EXPORT_SYMBOL(eddnr);
#endif
+
+#ifdef CONFIG_X86_STACK_CHECK
+extern void mcount(void);
+EXPORT_SYMBOL(mcount);
+#endif
diff -Nru a/arch/i386/kernel/init_task.c b/arch/i386/kernel/init_task.c
--- a/arch/i386/kernel/init_task.c Thu Oct 31 11:13:28 2002
+++ b/arch/i386/kernel/init_task.c Thu Oct 31 11:13:28 2002
@@ -16,6 +16,10 @@
union thread_union init_irq_union
__attribute__((__section__(".data.init_task")));
+#ifdef CONFIG_X86_STACK_CHECK
+union thread_union stack_overflow_stack
+ __attribute__((__section__(".data.init_task")));
+#endif
/*
* Initial thread structure.
diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c Thu Oct 31 11:13:28 2002
+++ b/arch/i386/kernel/process.c Thu Oct 31 11:13:28 2002
@@ -156,7 +156,25 @@
__setup("idle=", idle_setup);
-void show_regs(struct pt_regs * regs)
+void stack_overflow(unsigned long esp, unsigned long eip)
+{
+ int panicing = ((esp&(THREAD_SIZE-1)) <= STACK_PANIC);
+
+ printk( "esp: 0x%x masked: 0x%x STACK_PANIC:0x%x %d %d\n",
+ esp, (esp&(THREAD_SIZE-1)), STACK_PANIC, (((esp&(THREAD_SIZE-1)) <= STACK_PANIC)), panicing );
+
+ if (panicing)
+ print_symbol("stack overflow from %s\n", eip);
+ else
+ print_symbol("excessive stack use from %s\n", eip);
+ printk("esp: %p\n", (void*)esp);
+ show_trace((void*)esp);
+
+ if (panicing)
+ panic("stack overflow\n");
+}
+
+asmlinkage void show_regs(struct pt_regs * regs)
{
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
diff -Nru a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
--- a/include/asm-i386/thread_info.h Thu Oct 31 11:13:28 2002
+++ b/include/asm-i386/thread_info.h Thu Oct 31 11:13:28 2002
@@ -60,6 +60,8 @@
*/
#define THREAD_ORDER 1
#define INIT_THREAD_SIZE THREAD_SIZE
+#define STACK_PANIC 0x200ul
+#define STACK_WARN ((THREAD_SIZE)>>1)
#ifndef __ASSEMBLY__
#define INIT_THREAD_INFO(tsk) \
next prev parent reply other threads:[~2002-10-31 19:16 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-10-31 19:18 [PATCH] (1/3) cleanup thread info on x86 David C. Hansen
2002-10-31 19:20 ` [PATCH] (2/3) per-cpu interrupt stacks for x86 David C. Hansen
2002-10-31 19:20 ` David C. Hansen [this message]
2002-10-31 21:30 ` [PATCH] (3/3) stack overflow checking " Dave Jones
2002-10-31 22:08 ` David C. Hansen
2002-11-01 12:59 ` Alan Cox
2002-11-01 13:42 ` Dave Jones
-- strict thread matches above, loose matches on Subject: below --
2002-10-18 22:07 Dave Hansen
2002-10-18 22:31 ` Dave Hansen
2002-10-18 22:48 ` Andreas Dilger
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=1036092052.4272.96.camel@nighthawk \
--to=haveblue@us.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@transmeta.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.