diff options
Diffstat (limited to 'kernel/time/posix-cpu-timers.c')
-rw-r--r-- | kernel/time/posix-cpu-timers.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index ec6258c9cde5..1563ca22cf1f 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -12,6 +12,7 @@ #include <trace/events/timer.h> #include <linux/tick.h> #include <linux/workqueue.h> +#include <linux/compat.h> #include "posix-timers.h" @@ -1243,10 +1244,9 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, timer.it_process = current; if (!error) { static struct itimerspec64 zero_it; - struct restart_block *restart = ¤t->restart_block; - struct timespec __user *rmtp; + struct restart_block *restart; - memset(&it, 0, sizeof it); + memset(&it, 0, sizeof(it)); it.it_value = *rqtp; spin_lock_irq(&timer.it_lock); @@ -1311,12 +1311,20 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, /* * Report back to the user the time still remaining. */ - rmtp = restart->nanosleep.rmtp; - if (rmtp) { + restart = ¤t->restart_block; + if (restart->nanosleep.type != TT_NONE) { struct timespec ts; ts = timespec64_to_timespec(it.it_value); - if (copy_to_user(rmtp, &ts, sizeof(*rmtp))) +#ifdef CONFIG_COMPAT + if (restart->nanosleep.type == TT_COMPAT) { + if (compat_put_timespec(&ts, + restart->nanosleep.compat_rmtp)) + return -EFAULT; + } else +#endif + if (copy_to_user(restart->nanosleep.rmtp, &ts, + sizeof(ts))) return -EFAULT; } restart->nanosleep.expires = timespec64_to_ns(rqtp); |