Skip to content

Commit

Permalink
posix-timers: Move compat_timer_create() to native, get rid of set_fs()
Browse files Browse the repository at this point in the history
Signed-off-by: Al Viro <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: John Stultz <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
  • Loading branch information
Al Viro authored and KAGA-KOKO committed Jun 13, 2017
1 parent d822cdc commit 2482097
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 36 deletions.
18 changes: 0 additions & 18 deletions kernel/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,24 +580,6 @@ int put_compat_itimerspec(struct compat_itimerspec __user *dst,
return 0;
}

COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,
struct compat_sigevent __user *, timer_event_spec,
timer_t __user *, created_timer_id)
{
struct sigevent __user *event = NULL;

if (timer_event_spec) {
struct sigevent kevent;

event = compat_alloc_user_space(sizeof(*event));
if (get_compat_sigevent(&kevent, timer_event_spec) ||
copy_to_user(event, &kevent, sizeof(*event)))
return -EFAULT;
}

return sys_timer_create(which_clock, event, created_timer_id);
}

/*
* We currently only need the following fields from the sigevent
* structure: sigev_value, sigev_signo, sig_notify and (sometimes
Expand Down
1 change: 1 addition & 0 deletions kernel/time/posix-stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ SYS_NI(setitimer);
#ifdef __ARCH_WANT_SYS_ALARM
SYS_NI(alarm);
#endif
COMPAT_SYS_NI(timer_create);
COMPAT_SYS_NI(clock_adjtime);
COMPAT_SYS_NI(timer_settime);
COMPAT_SYS_NI(timer_gettime);
Expand Down
59 changes: 41 additions & 18 deletions kernel/time/posix-timers.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,15 +490,12 @@ static int common_timer_create(struct k_itimer *new_timer)
}

/* Create a POSIX.1b interval timer. */

SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
struct sigevent __user *, timer_event_spec,
timer_t __user *, created_timer_id)
static int do_timer_create(clockid_t which_clock, struct sigevent *event,
timer_t __user *created_timer_id)
{
const struct k_clock *kc = clockid_to_kclock(which_clock);
struct k_itimer *new_timer;
int error, new_timer_id;
sigevent_t event;
int it_id_set = IT_ID_NOT_SET;

if (!kc)
Expand All @@ -523,29 +520,25 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
new_timer->kclock = kc;
new_timer->it_overrun = -1;

if (timer_event_spec) {
if (copy_from_user(&event, timer_event_spec, sizeof (event))) {
error = -EFAULT;
goto out;
}
if (event) {
rcu_read_lock();
new_timer->it_pid = get_pid(good_sigevent(&event));
new_timer->it_pid = get_pid(good_sigevent(event));
rcu_read_unlock();
if (!new_timer->it_pid) {
error = -EINVAL;
goto out;
}
new_timer->it_sigev_notify = event->sigev_notify;
new_timer->sigq->info.si_signo = event->sigev_signo;
new_timer->sigq->info.si_value = event->sigev_value;
} else {
memset(&event.sigev_value, 0, sizeof(event.sigev_value));
event.sigev_notify = SIGEV_SIGNAL;
event.sigev_signo = SIGALRM;
event.sigev_value.sival_int = new_timer->it_id;
new_timer->it_sigev_notify = SIGEV_SIGNAL;
new_timer->sigq->info.si_signo = SIGALRM;
memset(&new_timer->sigq->info.si_value, 0, sizeof(sigval_t));
new_timer->sigq->info.si_value.sival_int = new_timer->it_id;
new_timer->it_pid = get_pid(task_tgid(current));
}

new_timer->it_sigev_notify = event.sigev_notify;
new_timer->sigq->info.si_signo = event.sigev_signo;
new_timer->sigq->info.si_value = event.sigev_value;
new_timer->sigq->info.si_tid = new_timer->it_id;
new_timer->sigq->info.si_code = SI_TIMER;

Expand Down Expand Up @@ -576,6 +569,36 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
return error;
}

SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
struct sigevent __user *, timer_event_spec,
timer_t __user *, created_timer_id)
{
if (timer_event_spec) {
sigevent_t event;

if (copy_from_user(&event, timer_event_spec, sizeof (event)))
return -EFAULT;
return do_timer_create(which_clock, &event, created_timer_id);
}
return do_timer_create(which_clock, NULL, created_timer_id);
}

#ifdef CONFIG_COMPAT
COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,
struct compat_sigevent __user *, timer_event_spec,
timer_t __user *, created_timer_id)
{
if (timer_event_spec) {
sigevent_t event;

if (get_compat_sigevent(&event, timer_event_spec))
return -EFAULT;
return do_timer_create(which_clock, &event, created_timer_id);
}
return do_timer_create(which_clock, NULL, created_timer_id);
}
#endif

/*
* Locking issues: We need to protect the result of the id look up until
* we get the timer locked down so it is not deleted under us. The
Expand Down

0 comments on commit 2482097

Please sign in to comment.