diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-07 04:42:39 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-06-13 18:00:45 -0400 |
commit | 2482097c6c0f01ad74c9b2cff120a519ac59846e (patch) | |
tree | c668168beaabac15908f30936dd6ddf786f3e64b | |
parent | d822cdcce43f9d4dcddbf9c68f9537d542ccc3c3 (diff) |
posix-timers: Move compat_timer_create() to native, get rid of set_fs()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20170607084241.28657-14-viro@ZenIV.linux.org.uk
-rw-r--r-- | kernel/compat.c | 18 | ||||
-rw-r--r-- | kernel/time/posix-stubs.c | 1 | ||||
-rw-r--r-- | kernel/time/posix-timers.c | 59 |
3 files changed, 42 insertions, 36 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index 582c38bfdf60..4544eb63edfa 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -580,24 +580,6 @@ int put_compat_itimerspec(struct compat_itimerspec __user *dst, | |||
580 | return 0; | 580 | return 0; |
581 | } | 581 | } |
582 | 582 | ||
583 | COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock, | ||
584 | struct compat_sigevent __user *, timer_event_spec, | ||
585 | timer_t __user *, created_timer_id) | ||
586 | { | ||
587 | struct sigevent __user *event = NULL; | ||
588 | |||
589 | if (timer_event_spec) { | ||
590 | struct sigevent kevent; | ||
591 | |||
592 | event = compat_alloc_user_space(sizeof(*event)); | ||
593 | if (get_compat_sigevent(&kevent, timer_event_spec) || | ||
594 | copy_to_user(event, &kevent, sizeof(*event))) | ||
595 | return -EFAULT; | ||
596 | } | ||
597 | |||
598 | return sys_timer_create(which_clock, event, created_timer_id); | ||
599 | } | ||
600 | |||
601 | /* | 583 | /* |
602 | * We currently only need the following fields from the sigevent | 584 | * We currently only need the following fields from the sigevent |
603 | * structure: sigev_value, sigev_signo, sig_notify and (sometimes | 585 | * structure: sigev_value, sigev_signo, sig_notify and (sometimes |
diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c index a375c31cb352..38f3b20efa29 100644 --- a/kernel/time/posix-stubs.c +++ b/kernel/time/posix-stubs.c | |||
@@ -41,6 +41,7 @@ SYS_NI(setitimer); | |||
41 | #ifdef __ARCH_WANT_SYS_ALARM | 41 | #ifdef __ARCH_WANT_SYS_ALARM |
42 | SYS_NI(alarm); | 42 | SYS_NI(alarm); |
43 | #endif | 43 | #endif |
44 | COMPAT_SYS_NI(timer_create); | ||
44 | COMPAT_SYS_NI(clock_adjtime); | 45 | COMPAT_SYS_NI(clock_adjtime); |
45 | COMPAT_SYS_NI(timer_settime); | 46 | COMPAT_SYS_NI(timer_settime); |
46 | COMPAT_SYS_NI(timer_gettime); | 47 | COMPAT_SYS_NI(timer_gettime); |
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 61a5fb91a3c7..c9f45a84fb8b 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c | |||
@@ -490,15 +490,12 @@ static int common_timer_create(struct k_itimer *new_timer) | |||
490 | } | 490 | } |
491 | 491 | ||
492 | /* Create a POSIX.1b interval timer. */ | 492 | /* Create a POSIX.1b interval timer. */ |
493 | 493 | static int do_timer_create(clockid_t which_clock, struct sigevent *event, | |
494 | SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, | 494 | timer_t __user *created_timer_id) |
495 | struct sigevent __user *, timer_event_spec, | ||
496 | timer_t __user *, created_timer_id) | ||
497 | { | 495 | { |
498 | const struct k_clock *kc = clockid_to_kclock(which_clock); | 496 | const struct k_clock *kc = clockid_to_kclock(which_clock); |
499 | struct k_itimer *new_timer; | 497 | struct k_itimer *new_timer; |
500 | int error, new_timer_id; | 498 | int error, new_timer_id; |
501 | sigevent_t event; | ||
502 | int it_id_set = IT_ID_NOT_SET; | 499 | int it_id_set = IT_ID_NOT_SET; |
503 | 500 | ||
504 | if (!kc) | 501 | if (!kc) |
@@ -523,29 +520,25 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, | |||
523 | new_timer->kclock = kc; | 520 | new_timer->kclock = kc; |
524 | new_timer->it_overrun = -1; | 521 | new_timer->it_overrun = -1; |
525 | 522 | ||
526 | if (timer_event_spec) { | 523 | if (event) { |
527 | if (copy_from_user(&event, timer_event_spec, sizeof (event))) { | ||
528 | error = -EFAULT; | ||
529 | goto out; | ||
530 | } | ||
531 | rcu_read_lock(); | 524 | rcu_read_lock(); |
532 | new_timer->it_pid = get_pid(good_sigevent(&event)); | 525 | new_timer->it_pid = get_pid(good_sigevent(event)); |
533 | rcu_read_unlock(); | 526 | rcu_read_unlock(); |
534 | if (!new_timer->it_pid) { | 527 | if (!new_timer->it_pid) { |
535 | error = -EINVAL; | 528 | error = -EINVAL; |
536 | goto out; | 529 | goto out; |
537 | } | 530 | } |
531 | new_timer->it_sigev_notify = event->sigev_notify; | ||
532 | new_timer->sigq->info.si_signo = event->sigev_signo; | ||
533 | new_timer->sigq->info.si_value = event->sigev_value; | ||
538 | } else { | 534 | } else { |
539 | memset(&event.sigev_value, 0, sizeof(event.sigev_value)); | 535 | new_timer->it_sigev_notify = SIGEV_SIGNAL; |
540 | event.sigev_notify = SIGEV_SIGNAL; | 536 | new_timer->sigq->info.si_signo = SIGALRM; |
541 | event.sigev_signo = SIGALRM; | 537 | memset(&new_timer->sigq->info.si_value, 0, sizeof(sigval_t)); |
542 | event.sigev_value.sival_int = new_timer->it_id; | 538 | new_timer->sigq->info.si_value.sival_int = new_timer->it_id; |
543 | new_timer->it_pid = get_pid(task_tgid(current)); | 539 | new_timer->it_pid = get_pid(task_tgid(current)); |
544 | } | 540 | } |
545 | 541 | ||
546 | new_timer->it_sigev_notify = event.sigev_notify; | ||
547 | new_timer->sigq->info.si_signo = event.sigev_signo; | ||
548 | new_timer->sigq->info.si_value = event.sigev_value; | ||
549 | new_timer->sigq->info.si_tid = new_timer->it_id; | 542 | new_timer->sigq->info.si_tid = new_timer->it_id; |
550 | new_timer->sigq->info.si_code = SI_TIMER; | 543 | new_timer->sigq->info.si_code = SI_TIMER; |
551 | 544 | ||
@@ -576,6 +569,36 @@ out: | |||
576 | return error; | 569 | return error; |
577 | } | 570 | } |
578 | 571 | ||
572 | SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, | ||
573 | struct sigevent __user *, timer_event_spec, | ||
574 | timer_t __user *, created_timer_id) | ||
575 | { | ||
576 | if (timer_event_spec) { | ||
577 | sigevent_t event; | ||
578 | |||
579 | if (copy_from_user(&event, timer_event_spec, sizeof (event))) | ||
580 | return -EFAULT; | ||
581 | return do_timer_create(which_clock, &event, created_timer_id); | ||
582 | } | ||
583 | return do_timer_create(which_clock, NULL, created_timer_id); | ||
584 | } | ||
585 | |||
586 | #ifdef CONFIG_COMPAT | ||
587 | COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock, | ||
588 | struct compat_sigevent __user *, timer_event_spec, | ||
589 | timer_t __user *, created_timer_id) | ||
590 | { | ||
591 | if (timer_event_spec) { | ||
592 | sigevent_t event; | ||
593 | |||
594 | if (get_compat_sigevent(&event, timer_event_spec)) | ||
595 | return -EFAULT; | ||
596 | return do_timer_create(which_clock, &event, created_timer_id); | ||
597 | } | ||
598 | return do_timer_create(which_clock, NULL, created_timer_id); | ||
599 | } | ||
600 | #endif | ||
601 | |||
579 | /* | 602 | /* |
580 | * Locking issues: We need to protect the result of the id look up until | 603 | * Locking issues: We need to protect the result of the id look up until |
581 | * we get the timer locked down so it is not deleted under us. The | 604 | * we get the timer locked down so it is not deleted under us. The |