lkml.org 
[lkml]   [2003]   [Jul]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH 2.5.74] Signal stack safety #2 i386 specific
On Sun, 6 July 2003 14:51:03 +0200, Jörn Engel wrote:
>
> My current best idea is to check, whether the stack pointer is valid
> before going to the signal stack. As long as it points to memory that
> is writable for the current process, things are not completely
> hopeless. When the stack is totally broken, kill that cancer cell.

Also stupid. People use a segfault handler on a signal stack,
*because* the previous stack may be broken.

Since any trick we try appears to (possibly) break some existing
software, the next idea is to add yet another flag to signal.h. With
this, the user can decide whether he want to get extra safety or not.

Comments?

Jörn

--
The only real mistake is the one from which we learn nothing.
-- John Powell

--- linux-2.5.74/arch/i386/kernel/signal.c~ss_i386 2003-07-07 10:30:30.000000000 +0200
+++ linux-2.5.74/arch/i386/kernel/signal.c 2003-07-07 10:31:09.000000000 +0200
@@ -181,6 +181,9 @@
}
}

+ if (sas_ss_flags(regs->esp) == 0)
+ current->flags &= ~PF_SS_ACTIVE;
+
err |= __get_user(*peax, &sc->eax);
return err;

@@ -317,9 +320,23 @@
esp = regs->esp;

/* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (sas_ss_flags(esp) == 0)
- esp = current->sas_ss_sp + current->sas_ss_size;
+ if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(esp) == 0)) {
+ /* If we have switches to the signal stack before,
+ * something bad has happened to it, asking for a
+ * segmentation fault.
+ * If not, remember it for the next time
+ */
+ if ((ka->sa.sa_flags & SA_KERNEL_RET) &&
+ (current->flags & PF_SS_ACTIVE)) {
+ ka->sa.sa_handler = SIG_DFL;
+ force_sig(SIGSEGV, current);
+ /* XXX would it be simpler to return some broken
+ * value like NULL and have the calling function
+ * signal the segv?
+ */
+ }
+ current->flags |= PF_SS_ACTIVE;
+ esp = current->sas_ss_sp + current->sas_ss_size;
}

/* This is the legacy signal stack switching. */
--- linux-2.5.74/include/asm-i386/signal.h~ss_i386 2003-07-07 10:30:30.000000000 +0200
+++ linux-2.5.74/include/asm-i386/signal.h 2003-07-07 11:29:42.000000000 +0200
@@ -76,6 +76,8 @@
* SA_FLAGS values:
*
* SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_KERNEL_RET indices that the handler returns through the kernel, not
+ * with longjmp or similar.
* SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
* SA_RESTART flag to get restarting signals (which were the default long ago)
* SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
@@ -89,6 +91,7 @@
#define SA_NOCLDSTOP 0x00000001u
#define SA_NOCLDWAIT 0x00000002u
#define SA_SIGINFO 0x00000004u
+#define SA_KERNEL_RET 0x01000000u
#define SA_ONSTACK 0x08000000u
#define SA_RESTART 0x10000000u
#define SA_NODEFER 0x40000000u
-
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/
\
 
 \ /
  Last update: 2005-03-22 13:46    [from the cache]
©2003-2011 Jasper Spaans. Advertise on this site