]> err.no Git - linux-2.6/commitdiff
[XTENSA] Add support for the sa_restorer function
authorChris Zankel <chris@zankel.net>
Fri, 11 Jan 2008 19:44:17 +0000 (11:44 -0800)
committerChris Zankel <chris@zankel.net>
Thu, 14 Feb 2008 01:42:31 +0000 (17:42 -0800)
Supporting the sa_restorer function allows for better security
since the sigreturn system call doesn't need to be placed on
the stack, so the stack doesn't need to be executable. This
requires support from the c-library as it has to provide the
restorer function.

Signed-off-by: Chris Zankel <chris@zankel.net>
arch/xtensa/kernel/signal.c

index 299be42d116b498559cf8a9c5979009e21e335d1..f2220b5bdce64daff9d0b75306e713159b334502 100644 (file)
@@ -381,14 +381,19 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= setup_sigcontext(frame, regs);
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 
-       /* Create sys_rt_sigreturn syscall in stack frame */
+       if (ka->sa.sa_flags & SA_RESTORER) {
+               ra = (unsigned long)ka->sa.sa_restorer;
+       } else {
 
-       err |= gen_return_code(frame->retcode);
+               /* Create sys_rt_sigreturn syscall in stack frame */
 
-       if (err) {
-               goto give_sigsegv;
+               err |= gen_return_code(frame->retcode);
+
+               if (err) {
+                       goto give_sigsegv;
+               }
+               ra = (unsigned long) frame->retcode;
        }
-               
 
        /* 
         * Create signal handler execution context.
@@ -402,7 +407,6 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        /* Set up a stack frame for a call4
         * Note: PS.CALLINC is set to one by start_thread
         */
-       ra = (unsigned long) frame->retcode;
        regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000;
        regs->areg[6] = (unsigned long) signal;
        regs->areg[7] = (unsigned long) &frame->info;