diff options
author | Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> | 2008-09-12 20:01:09 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-09-14 09:35:34 -0400 |
commit | 3d0aedd9538e6be8afec1a9d8b084bf90bc91495 (patch) | |
tree | f1dd505b2a703343a0c5dc0ab3a7c2e98949f1f8 | |
parent | 764e8d128f9343027cf09afe8a145e8ff186e129 (diff) |
x86: signal: put give_sigsegv of setup frames together
When setup frame fails, force_sigsegv is called and returns -EFAULT.
There is similar code in ia32_setup_frame(), ia32_setup_rt_frame(),
__setup_frame() and __setup_rt_frame().
Make them identical.
No change in functionality intended.
Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/ia32/ia32_signal.c | 26 | ||||
-rw-r--r-- | arch/x86/kernel/signal_32.c | 31 | ||||
-rw-r--r-- | arch/x86/kernel/signal_64.c | 17 |
3 files changed, 32 insertions, 42 deletions
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 8d64c1bc8474..5f42cfcc1c5a 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c | |||
@@ -444,21 +444,21 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, | |||
444 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); | 444 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); |
445 | 445 | ||
446 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 446 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
447 | goto give_sigsegv; | 447 | return -EFAULT; |
448 | 448 | ||
449 | err |= __put_user(sig, &frame->sig); | 449 | err |= __put_user(sig, &frame->sig); |
450 | if (err) | 450 | if (err) |
451 | goto give_sigsegv; | 451 | return -EFAULT; |
452 | 452 | ||
453 | err |= ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]); | 453 | err |= ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]); |
454 | if (err) | 454 | if (err) |
455 | goto give_sigsegv; | 455 | return -EFAULT; |
456 | 456 | ||
457 | if (_COMPAT_NSIG_WORDS > 1) { | 457 | if (_COMPAT_NSIG_WORDS > 1) { |
458 | err |= __copy_to_user(frame->extramask, &set->sig[1], | 458 | err |= __copy_to_user(frame->extramask, &set->sig[1], |
459 | sizeof(frame->extramask)); | 459 | sizeof(frame->extramask)); |
460 | if (err) | 460 | if (err) |
461 | goto give_sigsegv; | 461 | return -EFAULT; |
462 | } | 462 | } |
463 | 463 | ||
464 | if (ka->sa.sa_flags & SA_RESTORER) { | 464 | if (ka->sa.sa_flags & SA_RESTORER) { |
@@ -479,7 +479,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, | |||
479 | */ | 479 | */ |
480 | err |= __copy_to_user(frame->retcode, &code, 8); | 480 | err |= __copy_to_user(frame->retcode, &code, 8); |
481 | if (err) | 481 | if (err) |
482 | goto give_sigsegv; | 482 | return -EFAULT; |
483 | 483 | ||
484 | /* Set up registers for signal handler */ | 484 | /* Set up registers for signal handler */ |
485 | regs->sp = (unsigned long) frame; | 485 | regs->sp = (unsigned long) frame; |
@@ -502,10 +502,6 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, | |||
502 | #endif | 502 | #endif |
503 | 503 | ||
504 | return 0; | 504 | return 0; |
505 | |||
506 | give_sigsegv: | ||
507 | force_sigsegv(sig, current); | ||
508 | return -EFAULT; | ||
509 | } | 505 | } |
510 | 506 | ||
511 | int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 507 | int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
@@ -533,14 +529,14 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
533 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); | 529 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); |
534 | 530 | ||
535 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 531 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
536 | goto give_sigsegv; | 532 | return -EFAULT; |
537 | 533 | ||
538 | err |= __put_user(sig, &frame->sig); | 534 | err |= __put_user(sig, &frame->sig); |
539 | err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo); | 535 | err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo); |
540 | err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc); | 536 | err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc); |
541 | err |= copy_siginfo_to_user32(&frame->info, info); | 537 | err |= copy_siginfo_to_user32(&frame->info, info); |
542 | if (err) | 538 | if (err) |
543 | goto give_sigsegv; | 539 | return -EFAULT; |
544 | 540 | ||
545 | /* Create the ucontext. */ | 541 | /* Create the ucontext. */ |
546 | if (cpu_has_xsave) | 542 | if (cpu_has_xsave) |
@@ -556,7 +552,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
556 | regs, set->sig[0]); | 552 | regs, set->sig[0]); |
557 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | 553 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
558 | if (err) | 554 | if (err) |
559 | goto give_sigsegv; | 555 | return -EFAULT; |
560 | 556 | ||
561 | if (ka->sa.sa_flags & SA_RESTORER) | 557 | if (ka->sa.sa_flags & SA_RESTORER) |
562 | restorer = ka->sa.sa_restorer; | 558 | restorer = ka->sa.sa_restorer; |
@@ -571,7 +567,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
571 | */ | 567 | */ |
572 | err |= __copy_to_user(frame->retcode, &code, 8); | 568 | err |= __copy_to_user(frame->retcode, &code, 8); |
573 | if (err) | 569 | if (err) |
574 | goto give_sigsegv; | 570 | return -EFAULT; |
575 | 571 | ||
576 | /* Set up registers for signal handler */ | 572 | /* Set up registers for signal handler */ |
577 | regs->sp = (unsigned long) frame; | 573 | regs->sp = (unsigned long) frame; |
@@ -599,8 +595,4 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
599 | #endif | 595 | #endif |
600 | 596 | ||
601 | return 0; | 597 | return 0; |
602 | |||
603 | give_sigsegv: | ||
604 | force_sigsegv(sig, current); | ||
605 | return -EFAULT; | ||
606 | } | 598 | } |
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index b668efc18eae..1c22e0067fe7 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c | |||
@@ -349,21 +349,21 @@ __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
349 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); | 349 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); |
350 | 350 | ||
351 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 351 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
352 | goto give_sigsegv; | 352 | return -EFAULT; |
353 | 353 | ||
354 | err = __put_user(sig, &frame->sig); | 354 | err = __put_user(sig, &frame->sig); |
355 | if (err) | 355 | if (err) |
356 | goto give_sigsegv; | 356 | return -EFAULT; |
357 | 357 | ||
358 | err = setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]); | 358 | err = setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]); |
359 | if (err) | 359 | if (err) |
360 | goto give_sigsegv; | 360 | return -EFAULT; |
361 | 361 | ||
362 | if (_NSIG_WORDS > 1) { | 362 | if (_NSIG_WORDS > 1) { |
363 | err = __copy_to_user(&frame->extramask, &set->sig[1], | 363 | err = __copy_to_user(&frame->extramask, &set->sig[1], |
364 | sizeof(frame->extramask)); | 364 | sizeof(frame->extramask)); |
365 | if (err) | 365 | if (err) |
366 | goto give_sigsegv; | 366 | return -EFAULT; |
367 | } | 367 | } |
368 | 368 | ||
369 | if (current->mm->context.vdso) | 369 | if (current->mm->context.vdso) |
@@ -388,7 +388,7 @@ __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
388 | err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); | 388 | err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); |
389 | 389 | ||
390 | if (err) | 390 | if (err) |
391 | goto give_sigsegv; | 391 | return -EFAULT; |
392 | 392 | ||
393 | /* Set up registers for signal handler */ | 393 | /* Set up registers for signal handler */ |
394 | regs->sp = (unsigned long)frame; | 394 | regs->sp = (unsigned long)frame; |
@@ -403,10 +403,6 @@ __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
403 | regs->cs = __USER_CS; | 403 | regs->cs = __USER_CS; |
404 | 404 | ||
405 | return 0; | 405 | return 0; |
406 | |||
407 | give_sigsegv: | ||
408 | force_sigsegv(sig, current); | ||
409 | return -EFAULT; | ||
410 | } | 406 | } |
411 | 407 | ||
412 | static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 408 | static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
@@ -420,14 +416,14 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
420 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); | 416 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); |
421 | 417 | ||
422 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 418 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
423 | goto give_sigsegv; | 419 | return -EFAULT; |
424 | 420 | ||
425 | err |= __put_user(sig, &frame->sig); | 421 | err |= __put_user(sig, &frame->sig); |
426 | err |= __put_user(&frame->info, &frame->pinfo); | 422 | err |= __put_user(&frame->info, &frame->pinfo); |
427 | err |= __put_user(&frame->uc, &frame->puc); | 423 | err |= __put_user(&frame->uc, &frame->puc); |
428 | err |= copy_siginfo_to_user(&frame->info, info); | 424 | err |= copy_siginfo_to_user(&frame->info, info); |
429 | if (err) | 425 | if (err) |
430 | goto give_sigsegv; | 426 | return -EFAULT; |
431 | 427 | ||
432 | /* Create the ucontext. */ | 428 | /* Create the ucontext. */ |
433 | if (cpu_has_xsave) | 429 | if (cpu_has_xsave) |
@@ -443,7 +439,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
443 | regs, set->sig[0]); | 439 | regs, set->sig[0]); |
444 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | 440 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
445 | if (err) | 441 | if (err) |
446 | goto give_sigsegv; | 442 | return -EFAULT; |
447 | 443 | ||
448 | /* Set up to return from userspace. */ | 444 | /* Set up to return from userspace. */ |
449 | restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); | 445 | restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); |
@@ -463,7 +459,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
463 | err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); | 459 | err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); |
464 | 460 | ||
465 | if (err) | 461 | if (err) |
466 | goto give_sigsegv; | 462 | return -EFAULT; |
467 | 463 | ||
468 | /* Set up registers for signal handler */ | 464 | /* Set up registers for signal handler */ |
469 | regs->sp = (unsigned long)frame; | 465 | regs->sp = (unsigned long)frame; |
@@ -478,10 +474,6 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
478 | regs->cs = __USER_CS; | 474 | regs->cs = __USER_CS; |
479 | 475 | ||
480 | return 0; | 476 | return 0; |
481 | |||
482 | give_sigsegv: | ||
483 | force_sigsegv(sig, current); | ||
484 | return -EFAULT; | ||
485 | } | 477 | } |
486 | 478 | ||
487 | /* | 479 | /* |
@@ -506,6 +498,11 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
506 | else | 498 | else |
507 | ret = __setup_frame(usig, ka, set, regs); | 499 | ret = __setup_frame(usig, ka, set, regs); |
508 | 500 | ||
501 | if (ret) { | ||
502 | force_sigsegv(sig, current); | ||
503 | return -EFAULT; | ||
504 | } | ||
505 | |||
509 | return ret; | 506 | return ret; |
510 | } | 507 | } |
511 | 508 | ||
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index 43e6862fc7a2..3b79e179ba3a 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c | |||
@@ -215,12 +215,12 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
215 | frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8; | 215 | frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8; |
216 | 216 | ||
217 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 217 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
218 | goto give_sigsegv; | 218 | return -EFAULT; |
219 | 219 | ||
220 | if (ka->sa.sa_flags & SA_SIGINFO) { | 220 | if (ka->sa.sa_flags & SA_SIGINFO) { |
221 | err |= copy_siginfo_to_user(&frame->info, info); | 221 | err |= copy_siginfo_to_user(&frame->info, info); |
222 | if (err) | 222 | if (err) |
223 | goto give_sigsegv; | 223 | return -EFAULT; |
224 | } | 224 | } |
225 | 225 | ||
226 | /* Create the ucontext. */ | 226 | /* Create the ucontext. */ |
@@ -248,11 +248,11 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
248 | err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); | 248 | err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); |
249 | } else { | 249 | } else { |
250 | /* could use a vstub here */ | 250 | /* could use a vstub here */ |
251 | goto give_sigsegv; | 251 | return -EFAULT; |
252 | } | 252 | } |
253 | 253 | ||
254 | if (err) | 254 | if (err) |
255 | goto give_sigsegv; | 255 | return -EFAULT; |
256 | 256 | ||
257 | /* Set up registers for signal handler */ | 257 | /* Set up registers for signal handler */ |
258 | regs->di = sig; | 258 | regs->di = sig; |
@@ -272,10 +272,6 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
272 | regs->cs = __USER_CS; | 272 | regs->cs = __USER_CS; |
273 | 273 | ||
274 | return 0; | 274 | return 0; |
275 | |||
276 | give_sigsegv: | ||
277 | force_sigsegv(sig, current); | ||
278 | return -EFAULT; | ||
279 | } | 275 | } |
280 | 276 | ||
281 | /* | 277 | /* |
@@ -297,6 +293,11 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
297 | #endif | 293 | #endif |
298 | ret = __setup_rt_frame(sig, ka, info, set, regs); | 294 | ret = __setup_rt_frame(sig, ka, info, set, regs); |
299 | 295 | ||
296 | if (ret) { | ||
297 | force_sigsegv(sig, current); | ||
298 | return -EFAULT; | ||
299 | } | ||
300 | |||
300 | return ret; | 301 | return ret; |
301 | } | 302 | } |
302 | 303 | ||