diff options
| -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 | ||
