aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/signal_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/signal_64.c')
-rw-r--r--arch/x86/kernel/signal_64.c62
1 files changed, 30 insertions, 32 deletions
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index b45ef8ddd651..87a9c2f28d99 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -19,9 +19,10 @@
19#include <linux/stddef.h> 19#include <linux/stddef.h>
20#include <linux/personality.h> 20#include <linux/personality.h>
21#include <linux/compiler.h> 21#include <linux/compiler.h>
22#include <linux/uaccess.h>
23
22#include <asm/processor.h> 24#include <asm/processor.h>
23#include <asm/ucontext.h> 25#include <asm/ucontext.h>
24#include <asm/uaccess.h>
25#include <asm/i387.h> 26#include <asm/i387.h>
26#include <asm/proto.h> 27#include <asm/proto.h>
27#include <asm/ia32_unistd.h> 28#include <asm/ia32_unistd.h>
@@ -41,11 +42,6 @@
41# define FIX_EFLAGS __FIX_EFLAGS 42# define FIX_EFLAGS __FIX_EFLAGS
42#endif 43#endif
43 44
44int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
45 sigset_t *set, struct pt_regs * regs);
46int ia32_setup_frame(int sig, struct k_sigaction *ka,
47 sigset_t *set, struct pt_regs * regs);
48
49asmlinkage long 45asmlinkage long
50sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 46sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
51 struct pt_regs *regs) 47 struct pt_regs *regs)
@@ -119,7 +115,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
119 /* Always make any pending restarted system calls return -EINTR */ 115 /* Always make any pending restarted system calls return -EINTR */
120 current_thread_info()->restart_block.fn = do_no_restart_syscall; 116 current_thread_info()->restart_block.fn = do_no_restart_syscall;
121 117
122#define COPY(x) err |= __get_user(regs->x, &sc->x) 118#define COPY(x) (err |= __get_user(regs->x, &sc->x))
123 119
124 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); 120 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
125 COPY(dx); COPY(cx); COPY(ip); 121 COPY(dx); COPY(cx); COPY(ip);
@@ -149,7 +145,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
149 } 145 }
150 146
151 { 147 {
152 struct _fpstate __user * buf; 148 struct _fpstate __user *buf;
153 err |= __get_user(buf, &sc->fpstate); 149 err |= __get_user(buf, &sc->fpstate);
154 150
155 if (buf) { 151 if (buf) {
@@ -189,7 +185,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
189 current->blocked = set; 185 current->blocked = set;
190 recalc_sigpending(); 186 recalc_sigpending();
191 spin_unlock_irq(&current->sighand->siglock); 187 spin_unlock_irq(&current->sighand->siglock);
192 188
193 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax)) 189 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
194 goto badframe; 190 goto badframe;
195 191
@@ -199,16 +195,17 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
199 return ax; 195 return ax;
200 196
201badframe: 197badframe:
202 signal_fault(regs,frame,"sigreturn"); 198 signal_fault(regs, frame, "sigreturn");
203 return 0; 199 return 0;
204} 200}
205 201
206/* 202/*
207 * Set up a signal frame. 203 * Set up a signal frame.
208 */ 204 */
209 205
210static inline int 206static inline int
211setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me) 207setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
208 unsigned long mask, struct task_struct *me)
212{ 209{
213 int err = 0; 210 int err = 0;
214 211
@@ -264,35 +261,35 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
264} 261}
265 262
266static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 263static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
267 sigset_t *set, struct pt_regs * regs) 264 sigset_t *set, struct pt_regs *regs)
268{ 265{
269 struct rt_sigframe __user *frame; 266 struct rt_sigframe __user *frame;
270 struct _fpstate __user *fp = NULL; 267 struct _fpstate __user *fp = NULL;
271 int err = 0; 268 int err = 0;
272 struct task_struct *me = current; 269 struct task_struct *me = current;
273 270
274 if (used_math()) { 271 if (used_math()) {
275 fp = get_stack(ka, regs, sizeof(struct _fpstate)); 272 fp = get_stack(ka, regs, sizeof(struct _fpstate));
276 frame = (void __user *)round_down( 273 frame = (void __user *)round_down(
277 (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8; 274 (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
278 275
279 if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) 276 if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
280 goto give_sigsegv; 277 goto give_sigsegv;
281 278
282 if (save_i387(fp) < 0) 279 if (save_i387(fp) < 0)
283 err |= -1; 280 err |= -1;
284 } else 281 } else
285 frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8; 282 frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
286 283
287 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 284 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
288 goto give_sigsegv; 285 goto give_sigsegv;
289 286
290 if (ka->sa.sa_flags & SA_SIGINFO) { 287 if (ka->sa.sa_flags & SA_SIGINFO) {
291 err |= copy_siginfo_to_user(&frame->info, info); 288 err |= copy_siginfo_to_user(&frame->info, info);
292 if (err) 289 if (err)
293 goto give_sigsegv; 290 goto give_sigsegv;
294 } 291 }
295 292
296 /* Create the ucontext. */ 293 /* Create the ucontext. */
297 err |= __put_user(0, &frame->uc.uc_flags); 294 err |= __put_user(0, &frame->uc.uc_flags);
298 err |= __put_user(0, &frame->uc.uc_link); 295 err |= __put_user(0, &frame->uc.uc_link);
@@ -302,9 +299,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
302 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); 299 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
303 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me); 300 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
304 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate); 301 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
305 if (sizeof(*set) == 16) { 302 if (sizeof(*set) == 16) {
306 __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); 303 __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
307 __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); 304 __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
308 } else 305 } else
309 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 306 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
310 307
@@ -315,7 +312,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
315 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); 312 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
316 } else { 313 } else {
317 /* could use a vstub here */ 314 /* could use a vstub here */
318 goto give_sigsegv; 315 goto give_sigsegv;
319 } 316 }
320 317
321 if (err) 318 if (err)
@@ -323,7 +320,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
323 320
324 /* Set up registers for signal handler */ 321 /* Set up registers for signal handler */
325 regs->di = sig; 322 regs->di = sig;
326 /* In case the signal handler was declared without prototypes */ 323 /* In case the signal handler was declared without prototypes */
327 regs->ax = 0; 324 regs->ax = 0;
328 325
329 /* This also works for non SA_SIGINFO handlers because they expect the 326 /* This also works for non SA_SIGINFO handlers because they expect the
@@ -376,7 +373,7 @@ static long current_syscall_ret(struct pt_regs *regs)
376 373
377/* 374/*
378 * OK, we're invoking a handler 375 * OK, we're invoking a handler
379 */ 376 */
380 377
381static int 378static int
382handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 379handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
@@ -420,7 +417,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
420 ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs); 417 ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs);
421 else 418 else
422 ret = ia32_setup_frame(sig, ka, oldset, regs); 419 ret = ia32_setup_frame(sig, ka, oldset, regs);
423 } else 420 } else
424#endif 421#endif
425 ret = setup_rt_frame(sig, ka, info, oldset, regs); 422 ret = setup_rt_frame(sig, ka, info, oldset, regs);
426 423
@@ -448,9 +445,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
448 ptrace_notify(SIGTRAP); 445 ptrace_notify(SIGTRAP);
449 446
450 spin_lock_irq(&current->sighand->siglock); 447 spin_lock_irq(&current->sighand->siglock);
451 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 448 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
452 if (!(ka->sa.sa_flags & SA_NODEFER)) 449 if (!(ka->sa.sa_flags & SA_NODEFER))
453 sigaddset(&current->blocked,sig); 450 sigaddset(&current->blocked, sig);
454 recalc_sigpending(); 451 recalc_sigpending();
455 spin_unlock_irq(&current->sighand->siglock); 452 spin_unlock_irq(&current->sighand->siglock);
456 } 453 }
@@ -552,14 +549,15 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
552} 549}
553 550
554void signal_fault(struct pt_regs *regs, void __user *frame, char *where) 551void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
555{ 552{
556 struct task_struct *me = current; 553 struct task_struct *me = current;
557 if (show_unhandled_signals && printk_ratelimit()) { 554 if (show_unhandled_signals && printk_ratelimit()) {
558 printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx", 555 printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
559 me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax); 556 me->comm, me->pid, where, frame, regs->ip,
557 regs->sp, regs->orig_ax);
560 print_vma_addr(" in ", regs->ip); 558 print_vma_addr(" in ", regs->ip);
561 printk("\n"); 559 printk("\n");
562 } 560 }
563 561
564 force_sig(SIGSEGV, me); 562 force_sig(SIGSEGV, me);
565} 563}