aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Zankel <chris@zankel.net>2008-01-11 14:44:17 -0500
committerChris Zankel <chris@zankel.net>2008-02-13 20:42:31 -0500
commit44c64e6b15ceab6a4927f54e1081a74ba096b95a (patch)
treefc96c7ddee6fa82655ada03f9f0ba2e9badf3d32
parentc658eac628aa8df040dfe614556d95e6da3a9ffb (diff)
[XTENSA] Add support for the sa_restorer function
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>
-rw-r--r--arch/xtensa/kernel/signal.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index 299be42d116b..f2220b5bdce6 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -381,14 +381,19 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
381 err |= setup_sigcontext(frame, regs); 381 err |= setup_sigcontext(frame, regs);
382 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 382 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
383 383
384 /* Create sys_rt_sigreturn syscall in stack frame */ 384 if (ka->sa.sa_flags & SA_RESTORER) {
385 ra = (unsigned long)ka->sa.sa_restorer;
386 } else {
385 387
386 err |= gen_return_code(frame->retcode); 388 /* Create sys_rt_sigreturn syscall in stack frame */
387 389
388 if (err) { 390 err |= gen_return_code(frame->retcode);
389 goto give_sigsegv; 391
392 if (err) {
393 goto give_sigsegv;
394 }
395 ra = (unsigned long) frame->retcode;
390 } 396 }
391
392 397
393 /* 398 /*
394 * Create signal handler execution context. 399 * Create signal handler execution context.
@@ -402,7 +407,6 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
402 /* Set up a stack frame for a call4 407 /* Set up a stack frame for a call4
403 * Note: PS.CALLINC is set to one by start_thread 408 * Note: PS.CALLINC is set to one by start_thread
404 */ 409 */
405 ra = (unsigned long) frame->retcode;
406 regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000; 410 regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000;
407 regs->areg[6] = (unsigned long) signal; 411 regs->areg[6] = (unsigned long) signal;
408 regs->areg[7] = (unsigned long) &frame->info; 412 regs->areg[7] = (unsigned long) &frame->info;