Commit 9c7984a0 authored by Linus Torvalds's avatar Linus Torvalds

Move x86 signal handler return stub to the vsyscall page,

and stop honoring the SA_RESTORER information.

This will prepare us for alternate signal handler returns.
parent ae4d9837
...@@ -378,17 +378,19 @@ static void setup_frame(int sig, struct k_sigaction *ka, ...@@ -378,17 +378,19 @@ static void setup_frame(int sig, struct k_sigaction *ka,
if (err) if (err)
goto give_sigsegv; goto give_sigsegv;
/* Set up to return from userspace. If provided, use a stub /* Set up to return from userspace. */
already in userspace. */ err |= __put_user(fix_to_virt(FIX_VSYSCALL) + 32, &frame->pretcode);
if (ka->sa.sa_flags & SA_RESTORER) {
err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); /*
} else { * This is popl %eax ; movl $,%eax ; int $0x80
err |= __put_user(frame->retcode, &frame->pretcode); *
/* This is popl %eax ; movl $,%eax ; int $0x80 */ * WE DO NOT USE IT ANY MORE! It's only left here for historical
err |= __put_user(0xb858, (short *)(frame->retcode+0)); * reasons and because gdb uses it as a signature to notice
err |= __put_user(__NR_sigreturn, (int *)(frame->retcode+2)); * signal handler stack frames.
err |= __put_user(0x80cd, (short *)(frame->retcode+6)); */
} err |= __put_user(0xb858, (short *)(frame->retcode+0));
err |= __put_user(__NR_sigreturn, (int *)(frame->retcode+2));
err |= __put_user(0x80cd, (short *)(frame->retcode+6));
if (err) if (err)
goto give_sigsegv; goto give_sigsegv;
...@@ -453,17 +455,19 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -453,17 +455,19 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (err) if (err)
goto give_sigsegv; goto give_sigsegv;
/* Set up to return from userspace. If provided, use a stub /* Set up to return from userspace. */
already in userspace. */ err |= __put_user(fix_to_virt(FIX_VSYSCALL) + 64, &frame->pretcode);
if (ka->sa.sa_flags & SA_RESTORER) {
err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); /*
} else { * This is movl $,%eax ; int $0x80
err |= __put_user(frame->retcode, &frame->pretcode); *
/* This is movl $,%eax ; int $0x80 */ * WE DO NOT USE IT ANY MORE! It's only left here for historical
err |= __put_user(0xb8, (char *)(frame->retcode+0)); * reasons and because gdb uses it as a signature to notice
err |= __put_user(__NR_rt_sigreturn, (int *)(frame->retcode+1)); * signal handler stack frames.
err |= __put_user(0x80cd, (short *)(frame->retcode+5)); */
} err |= __put_user(0xb8, (char *)(frame->retcode+0));
err |= __put_user(__NR_rt_sigreturn, (int *)(frame->retcode+1));
err |= __put_user(0x80cd, (short *)(frame->retcode+5));
if (err) if (err)
goto give_sigsegv; goto give_sigsegv;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/msr.h> #include <asm/msr.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/unistd.h>
extern asmlinkage void sysenter_entry(void); extern asmlinkage void sysenter_entry(void);
...@@ -73,10 +74,23 @@ static int __init sysenter_setup(void) ...@@ -73,10 +74,23 @@ static int __init sysenter_setup(void)
0x59, /* pop %ecx */ 0x59, /* pop %ecx */
0xc3 /* ret */ 0xc3 /* ret */
}; };
static const char sigreturn[] = {
/* 32: sigreturn point */
0x58, /* popl %eax */
0xb8, __NR_sigreturn, 0, 0, 0, /* movl $__NR_sigreturn, %eax */
0xcd, 0x80, /* int $0x80 */
};
static const char rt_sigreturn[] = {
/* 64: rt_sigreturn point */
0xb8, __NR_rt_sigreturn, 0, 0, 0, /* movl $__NR_rt_sigreturn, %eax */
0xcd, 0x80, /* int $0x80 */
};
unsigned long page = get_zeroed_page(GFP_ATOMIC); unsigned long page = get_zeroed_page(GFP_ATOMIC);
__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY); __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY);
memcpy((void *) page, int80, sizeof(int80)); memcpy((void *) page, int80, sizeof(int80));
memcpy((void *)(page + 32), sigreturn, sizeof(sigreturn));
memcpy((void *)(page + 64), rt_sigreturn, sizeof(rt_sigreturn));
if (!boot_cpu_has(X86_FEATURE_SEP)) if (!boot_cpu_has(X86_FEATURE_SEP))
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment