[patch 3/3]: fix BAD_SYSCALL_EXIT lockup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello.

CONFIG_TRAP_BAD_SYSCALL_EXITS forgets to do
GET_THREAD_INFO(%ebp) before accessing the
TI_preempt_count(%ebp). This leads to an
accesses to the random addresses and kills
the machine. Also "int $3" does nothing good
by itself (it would just Oops AFAICS). And
it is misplaced, too. Obviously it never worked.

The attached patch moves the check to the
right place (to the syscall_exit path) and
replaces the "int $3" by the call to the
helper function that only prints some debug
info and doesn't crash the system.
This fully solves the reported problem.

Signed-off-by: Stas Sergeev <[email protected]>

--- linux/arch/i386/kernel/entry.S	2005-04-12 09:47:38.000000000 +0400
+++ linux/arch/i386/kernel/entry.S	2005-04-12 11:51:49.000000000 +0400
@@ -253,24 +253,15 @@
 	cli				# make sure we don't miss an interrupt
 					# setting need_resched or sigpending
 					# between sampling and the iret
+#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
+	movl %esp, %eax			# pt_regs pointer
+	call sys_call_exit
+#endif
 	movl TI_flags(%ebp), %ecx
 	testw $_TIF_ALLWORK_MASK, %cx	# current->work
 	jne syscall_exit_work
 
 restore_all:
-#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
-	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
-	movb CS(%esp), %al
-	testl $(VM_MASK | 3), %eax
-	jz resume_kernelX		# returning to kernel or vm86-space
-
-	cmpl $0,TI_preempt_count(%ebp)  # non-zero preempt_count ?
-	jz resume_kernelX
-
-        int $3
-
-resume_kernelX:
-#endif
 	movl EFLAGS(%esp), %eax		# mix EFLAGS, SS and CS
 	movb OLDSS(%esp), %ah
 	movb CS(%esp), %al
--- linux/arch/i386/kernel/kgdb_stub.c	2005-04-12 09:47:38.000000000 +0400
+++ linux/arch/i386/kernel/kgdb_stub.c	2005-04-12 13:23:57.000000000 +0400
@@ -2135,18 +2135,16 @@
 #endif
 #undef regs
 #ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
-asmlinkage void
-bad_sys_call_exit(int stuff)
+fastcall void sys_call_exit(struct pt_regs *regs)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stuff;
-	printk("Sys call %d return with %x preempt_count\n",
-	       (int) regs->orig_eax, preempt_count());
+	if (preempt_count())
+		printk("Sys call %d return with %x preempt_count\n",
+			(int) regs->orig_eax, preempt_count());
 }
 #endif
 #ifdef CONFIG_STACK_OVERFLOW_TEST
 #include <asm/kgdb.h>
-asmlinkage void
-stack_overflow(void)
+fastcall void stack_overflow(void)
 {
 #ifdef BREAKPOINT
 	BREAKPOINT;

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux