summaryrefslogtreecommitdiffstats
path: root/kernel/time/itimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/itimer.c')
-rw-r--r--kernel/time/itimer.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/kernel/time/itimer.c b/kernel/time/itimer.c
index 087d6a1279b8..2ef98a02376a 100644
--- a/kernel/time/itimer.c
+++ b/kernel/time/itimer.c
@@ -15,6 +15,7 @@
15#include <linux/posix-timers.h> 15#include <linux/posix-timers.h>
16#include <linux/hrtimer.h> 16#include <linux/hrtimer.h>
17#include <trace/events/timer.h> 17#include <trace/events/timer.h>
18#include <linux/compat.h>
18 19
19#include <linux/uaccess.h> 20#include <linux/uaccess.h>
20 21
@@ -116,6 +117,19 @@ SYSCALL_DEFINE2(getitimer, int, which, struct itimerval __user *, value)
116 return error; 117 return error;
117} 118}
118 119
120#ifdef CONFIG_COMPAT
121COMPAT_SYSCALL_DEFINE2(getitimer, int, which,
122 struct compat_itimerval __user *, it)
123{
124 struct itimerval kit;
125 int error = do_getitimer(which, &kit);
126
127 if (!error && put_compat_itimerval(it, &kit))
128 error = -EFAULT;
129 return error;
130}
131#endif
132
119 133
120/* 134/*
121 * The timer is automagically restarted, when interval != 0 135 * The timer is automagically restarted, when interval != 0
@@ -138,8 +152,12 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
138 u64 oval, nval, ointerval, ninterval; 152 u64 oval, nval, ointerval, ninterval;
139 struct cpu_itimer *it = &tsk->signal->it[clock_id]; 153 struct cpu_itimer *it = &tsk->signal->it[clock_id];
140 154
141 nval = timeval_to_ns(&value->it_value); 155 /*
142 ninterval = timeval_to_ns(&value->it_interval); 156 * Use the to_ktime conversion because that clamps the maximum
157 * value to KTIME_MAX and avoid multiplication overflows.
158 */
159 nval = ktime_to_ns(timeval_to_ktime(value->it_value));
160 ninterval = ktime_to_ns(timeval_to_ktime(value->it_interval));
143 161
144 spin_lock_irq(&tsk->sighand->siglock); 162 spin_lock_irq(&tsk->sighand->siglock);
145 163
@@ -294,3 +312,27 @@ SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value,
294 return -EFAULT; 312 return -EFAULT;
295 return 0; 313 return 0;
296} 314}
315
316#ifdef CONFIG_COMPAT
317COMPAT_SYSCALL_DEFINE3(setitimer, int, which,
318 struct compat_itimerval __user *, in,
319 struct compat_itimerval __user *, out)
320{
321 struct itimerval kin, kout;
322 int error;
323
324 if (in) {
325 if (get_compat_itimerval(&kin, in))
326 return -EFAULT;
327 } else {
328 memset(&kin, 0, sizeof(kin));
329 }
330
331 error = do_setitimer(which, &kin, out ? &kout : NULL);
332 if (error || !out)
333 return error;
334 if (put_compat_itimerval(out, &kout))
335 return -EFAULT;
336 return 0;
337}
338#endif