aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Ebbert <76306.1226@compuserve.com>2006-06-23 05:04:23 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-23 10:42:57 -0400
commit21528454f6dd18231ae20102f98aa8f51b6ec1b9 (patch)
treea167603f42c51c0e1a731ae9629305a11a5b8e44
parent1b61b910e99059abdd54c93aa70e84e076e33d16 (diff)
[PATCH] i386: let usermode execute the "enter" instruction
The i386 page fault handler does not allow enough slack when checking for userspace access below the current stack pointer. This prevents use of the enter instruction by user code. Fix this by allowing enough slack for "enter $65535,$31" to execute. Problem reported by Tomasz Malesinski <tmal@mimuw.edu.pl> Tested using this program, based on the original from Tomasz: .file "ovflow.S" .version "01.01" gcc2_compiled.: .section .rodata .LC0: .string "asdf\n" .text .align 4 .globl main .type main,@function main: nest_level=0 .rept 30 enter $0,$nest_level nest_level=nest_level+1 .endr enter $65535,$30 enter $65535,$31 addl $-12,%esp pushl $.LC0 call printf addl $16,%esp .L2: .rept 32 leave .endr ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.95.4 20011002 (Debian prerelease)" Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Cc: Andi Kleen <ak@muc.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/mm/fault.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 7f0fcf219a26..f38085ff3c3d 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -380,12 +380,12 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
380 goto bad_area; 380 goto bad_area;
381 if (error_code & 4) { 381 if (error_code & 4) {
382 /* 382 /*
383 * accessing the stack below %esp is always a bug. 383 * Accessing the stack below %esp is always a bug.
384 * The "+ 32" is there due to some instructions (like 384 * The large cushion allows instructions like enter
385 * pusha) doing post-decrement on the stack and that 385 * and pusha to work. ("enter $65535,$31" pushes
386 * doesn't show up until later.. 386 * 32 pointers and then decrements %esp by 65535.)
387 */ 387 */
388 if (address + 32 < regs->esp) 388 if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
389 goto bad_area; 389 goto bad_area;
390 } 390 }
391 if (expand_stack(vma, address)) 391 if (expand_stack(vma, address))