linux-stable/arch/i386
Alexander Nyberg f48d9663f1 [PATCH] x86 stack initialisation fix
The recent change fix-crash-in-entrys-restore_all.patch

 	childregs->esp = esp;

 	p->thread.esp = (unsigned long) childregs;
-	p->thread.esp0 = (unsigned long) (childregs+1);
+	p->thread.esp0 = (unsigned long) (childregs+1) - 8;

 	p->thread.eip = (unsigned long) ret_from_fork;

introduces an inconsistency between esp and esp0 before the task is run the
first time.  esp0 is no longer the actual start of the stack, but 8 bytes
off.

This shows itself clearly in a scenario when a ptracer that is set to also
ptrace eventual children traces program1 which then clones thread1.  Now
the ptracer wants to modify the registers of thread1.  The x86 ptrace
implementation bases it's knowledge about saved user-space registers upon
p->thread.esp0.  But this will be a few bytes off causing certain writes to
the kernel stack to overwrite a saved kernel function address making the
kernel when actually running thread1 jump out into user-space.  Very
spectacular.

The testcase I've used is:
/* start with strace -f ./a.out */
#include <pthread.h>
#include <stdio.h>

void *do_thread(void *p)
{
	for (;;);
}

int main()
{
	pthread_t one;
	pthread_create(&one, NULL, &do_thread, NULL);
	for (;;);
	return 0;
}

So, my solution is to instead of just adjusting esp0 that creates an
inconsitent state I adjust where the user-space registers are saved with -8
bytes.  This gives us the wanted extra bytes on the start of the stack and
esp0 is now correct.  This solves the issues I saw from the original
testcase from Mateusz Berezecki and has survived testing here.  I think
this should go into -mm a round or two first however as there might be some
cruft around depending on pt_regs lying on the start of the stack.  That
however would have broken with the first change too!

It's actually a 2-line diff but I had to move the comment of why the -8 bytes
are there a few lines up. Thanks to Zwane for helping me with this.

Signed-off-by: Alexander Nyberg <alexn@telia.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-05-05 16:36:30 -07:00
..
boot [PATCH] fbdev: edid.h cleanups 2005-05-01 08:59:23 -07:00
crypto Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
kernel [PATCH] x86 stack initialisation fix 2005-05-05 16:36:30 -07:00
lib Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mach-default Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mach-es7000 Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mach-generic Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mach-visws Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mach-voyager [PATCH] reparent_to_init cleanup 2005-04-16 15:26:01 -07:00
math-emu Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mm [PATCH] freepgt: hugetlb area is clean 2005-04-19 13:29:18 -07:00
oprofile [PATCH] Change synchronize_kernel to _rcu and _sched 2005-05-01 08:59:04 -07:00
pci [PATCH] irq and pci_ids for Intel ICH7DH & ICH7-M DH 2005-05-01 08:58:50 -07:00
power Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
defconfig Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
Kconfig [PATCH] ISA DMA Kconfig fixes - part 1 2005-05-04 07:33:13 -07:00
Kconfig.debug Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
Makefile [PATCH] kbuild/i386: re-introduce dependency on vmlinux for install target, and add kernel_install 2005-04-30 16:51:42 -07:00