Re: Linus BK tree crashes with PANIC: INIT: segmentation violation

From: Linus Torvalds (torvalds@transmeta.com)
Date: Sat Jan 11 2003 - 23:02:47 EST


On 11 Jan 2003, Derek Atkins wrote:
>
> The 'String of oopses' was a red herring. It was fixed sometime in early
> January. The PANIC: INIT: problem, however, is real, and was introduced
> by the following ChangeSet on January 7:
>
> D 1.972 03/01/07 10:08:55-08:00 torvalds@home.transmeta.com 15824 15815 2/0/1
> P ChangeSet
> C Move x86 signal handler return stub to the vsyscall page,
> C and stop honoring the SA_RESTORER information.
> C
> C This will prepare us for alternate signal handler returns.

Interesting.

I was afraid that somebody would actually be _using_ the SA_RESTORER thing
for some totally private version of signal handler return, but I was
hoping that wouldn't be the case.

SA_RESTORER was always a bit broken.. The functionality can trivially be
restored (suggested untested patch appended), since it makes it very hard
to improve on signal handling, since old binaries that use SA_RESTORER
will force our hand.

Oh, well. Can you verify whether this fixes it for you? And thanks for
hunting down the exact changeset.

Btw, what version of "init" are you running? It would be interesting to
see what it actually does, and obviously none of the machines I have
around have that init..

                Linus

----
===== arch/i386/kernel/signal.c 1.25 vs edited =====
--- 1.25/arch/i386/kernel/signal.c	Tue Jan  7 10:08:52 2003
+++ edited/arch/i386/kernel/signal.c	Sat Jan 11 19:59:57 2003
@@ -350,6 +350,7 @@
 static void setup_frame(int sig, struct k_sigaction *ka,
 			sigset_t *set, struct pt_regs * regs)
 {
+	void *restorer;
 	struct sigframe *frame;
 	int err = 0;
 
@@ -378,8 +379,12 @@
 	if (err)
 		goto give_sigsegv;
 
+	restorer = (void *) (fix_to_virt(FIX_VSYSCALL) + 32);
+	if (ka->sa.sa_flags & SA_RESTORER)
+		restorer = ka->sa.sa_restorer;
+
 	/* Set up to return from userspace.  */
-	err |= __put_user(fix_to_virt(FIX_VSYSCALL) + 32, &frame->pretcode);
+	err |= __put_user(restorer, &frame->pretcode);
 	 
 	/*
 	 * This is popl %eax ; movl $,%eax ; int $0x80
@@ -422,6 +427,7 @@
 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 			   sigset_t *set, struct pt_regs * regs)
 {
+	void *restorer;
 	struct rt_sigframe *frame;
 	int err = 0;
 
@@ -456,7 +462,10 @@
 		goto give_sigsegv;
 
 	/* Set up to return from userspace.  */
-	err |= __put_user(fix_to_virt(FIX_VSYSCALL) + 64, &frame->pretcode);
+	restorer = (void *) (fix_to_virt(FIX_VSYSCALL) + 64);
+	if (ka->sa.sa_flags & SA_RESTORER)
+		restorer = ka->sa.sa_restorer;
+	err |= __put_user(restorer, &frame->pretcode);
 	 
 	/*
 	 * This is movl $,%eax ; int $0x80

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Jan 15 2003 - 22:00:39 EST