hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/kernel/time/itimer.c
....@@ -1,7 +1,5 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /*
3
- * linux/kernel/itimer.c
4
- *
53 * Copyright (C) 1992 Darren Senn
64 */
75
....@@ -28,7 +26,7 @@
2826 * Returns the delta between the expiry time and now, which can be
2927 * less than zero or 1usec for an pending expired timer
3028 */
31
-static struct timeval itimer_get_remtime(struct hrtimer *timer)
29
+static struct timespec64 itimer_get_remtime(struct hrtimer *timer)
3230 {
3331 ktime_t rem = __hrtimer_get_remaining(timer, true);
3432
....@@ -43,11 +41,11 @@
4341 } else
4442 rem = 0;
4543
46
- return ktime_to_timeval(rem);
44
+ return ktime_to_timespec64(rem);
4745 }
4846
4947 static void get_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
50
- struct itimerval *const value)
48
+ struct itimerspec64 *const value)
5149 {
5250 u64 val, interval;
5351 struct cpu_itimer *it = &tsk->signal->it[clock_id];
....@@ -57,15 +55,10 @@
5755 val = it->expires;
5856 interval = it->incr;
5957 if (val) {
60
- struct task_cputime cputime;
61
- u64 t;
58
+ u64 t, samples[CPUCLOCK_MAX];
6259
63
- thread_group_cputimer(tsk, &cputime);
64
- if (clock_id == CPUCLOCK_PROF)
65
- t = cputime.utime + cputime.stime;
66
- else
67
- /* CPUCLOCK_VIRT */
68
- t = cputime.utime;
60
+ thread_group_sample_cputime(tsk, samples);
61
+ t = samples[clock_id];
6962
7063 if (val < t)
7164 /* about to fire */
....@@ -76,11 +69,11 @@
7669
7770 spin_unlock_irq(&tsk->sighand->siglock);
7871
79
- value->it_value = ns_to_timeval(val);
80
- value->it_interval = ns_to_timeval(interval);
72
+ value->it_value = ns_to_timespec64(val);
73
+ value->it_interval = ns_to_timespec64(interval);
8174 }
8275
83
-int do_getitimer(int which, struct itimerval *value)
76
+static int do_getitimer(int which, struct itimerspec64 *value)
8477 {
8578 struct task_struct *tsk = current;
8679
....@@ -89,7 +82,7 @@
8982 spin_lock_irq(&tsk->sighand->siglock);
9083 value->it_value = itimer_get_remtime(&tsk->signal->real_timer);
9184 value->it_interval =
92
- ktime_to_timeval(tsk->signal->it_real_incr);
85
+ ktime_to_timespec64(tsk->signal->it_real_incr);
9386 spin_unlock_irq(&tsk->sighand->siglock);
9487 break;
9588 case ITIMER_VIRTUAL:
....@@ -104,33 +97,58 @@
10497 return 0;
10598 }
10699
107
-SYSCALL_DEFINE2(getitimer, int, which, struct itimerval __user *, value)
100
+static int put_itimerval(struct __kernel_old_itimerval __user *o,
101
+ const struct itimerspec64 *i)
108102 {
109
- int error = -EFAULT;
110
- struct itimerval get_buffer;
103
+ struct __kernel_old_itimerval v;
111104
112
- if (value) {
113
- error = do_getitimer(which, &get_buffer);
114
- if (!error &&
115
- copy_to_user(value, &get_buffer, sizeof(get_buffer)))
116
- error = -EFAULT;
117
- }
105
+ v.it_interval.tv_sec = i->it_interval.tv_sec;
106
+ v.it_interval.tv_usec = i->it_interval.tv_nsec / NSEC_PER_USEC;
107
+ v.it_value.tv_sec = i->it_value.tv_sec;
108
+ v.it_value.tv_usec = i->it_value.tv_nsec / NSEC_PER_USEC;
109
+ return copy_to_user(o, &v, sizeof(struct __kernel_old_itimerval)) ? -EFAULT : 0;
110
+}
111
+
112
+
113
+SYSCALL_DEFINE2(getitimer, int, which, struct __kernel_old_itimerval __user *, value)
114
+{
115
+ struct itimerspec64 get_buffer;
116
+ int error = do_getitimer(which, &get_buffer);
117
+
118
+ if (!error && put_itimerval(value, &get_buffer))
119
+ error = -EFAULT;
118120 return error;
119121 }
120122
121
-#ifdef CONFIG_COMPAT
122
-COMPAT_SYSCALL_DEFINE2(getitimer, int, which,
123
- struct compat_itimerval __user *, it)
124
-{
125
- struct itimerval kit;
126
- int error = do_getitimer(which, &kit);
123
+#if defined(CONFIG_COMPAT) || defined(CONFIG_ALPHA)
124
+struct old_itimerval32 {
125
+ struct old_timeval32 it_interval;
126
+ struct old_timeval32 it_value;
127
+};
127128
128
- if (!error && put_compat_itimerval(it, &kit))
129
+static int put_old_itimerval32(struct old_itimerval32 __user *o,
130
+ const struct itimerspec64 *i)
131
+{
132
+ struct old_itimerval32 v32;
133
+
134
+ v32.it_interval.tv_sec = i->it_interval.tv_sec;
135
+ v32.it_interval.tv_usec = i->it_interval.tv_nsec / NSEC_PER_USEC;
136
+ v32.it_value.tv_sec = i->it_value.tv_sec;
137
+ v32.it_value.tv_usec = i->it_value.tv_nsec / NSEC_PER_USEC;
138
+ return copy_to_user(o, &v32, sizeof(struct old_itimerval32)) ? -EFAULT : 0;
139
+}
140
+
141
+COMPAT_SYSCALL_DEFINE2(getitimer, int, which,
142
+ struct old_itimerval32 __user *, value)
143
+{
144
+ struct itimerspec64 get_buffer;
145
+ int error = do_getitimer(which, &get_buffer);
146
+
147
+ if (!error && put_old_itimerval32(value, &get_buffer))
129148 error = -EFAULT;
130149 return error;
131150 }
132151 #endif
133
-
134152
135153 /*
136154 * The timer is automagically restarted, when interval != 0
....@@ -148,14 +166,14 @@
148166 }
149167
150168 static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
151
- const struct itimerval *const value,
152
- struct itimerval *const ovalue)
169
+ const struct itimerspec64 *const value,
170
+ struct itimerspec64 *const ovalue)
153171 {
154172 u64 oval, nval, ointerval, ninterval;
155173 struct cpu_itimer *it = &tsk->signal->it[clock_id];
156174
157
- nval = ktime_to_ns(timeval_to_ktime(value->it_value));
158
- ninterval = ktime_to_ns(timeval_to_ktime(value->it_interval));
175
+ nval = timespec64_to_ns(&value->it_value);
176
+ ninterval = timespec64_to_ns(&value->it_interval);
159177
160178 spin_lock_irq(&tsk->sighand->siglock);
161179
....@@ -174,8 +192,8 @@
174192 spin_unlock_irq(&tsk->sighand->siglock);
175193
176194 if (ovalue) {
177
- ovalue->it_value = ns_to_timeval(oval);
178
- ovalue->it_interval = ns_to_timeval(ointerval);
195
+ ovalue->it_value = ns_to_timespec64(oval);
196
+ ovalue->it_interval = ns_to_timespec64(ointerval);
179197 }
180198 }
181199
....@@ -185,18 +203,12 @@
185203 #define timeval_valid(t) \
186204 (((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
187205
188
-int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
206
+static int do_setitimer(int which, struct itimerspec64 *value,
207
+ struct itimerspec64 *ovalue)
189208 {
190209 struct task_struct *tsk = current;
191210 struct hrtimer *timer;
192211 ktime_t expires;
193
-
194
- /*
195
- * Validate the timevals in value.
196
- */
197
- if (!timeval_valid(&value->it_value) ||
198
- !timeval_valid(&value->it_interval))
199
- return -EINVAL;
200212
201213 switch (which) {
202214 case ITIMER_REAL:
....@@ -206,17 +218,18 @@
206218 if (ovalue) {
207219 ovalue->it_value = itimer_get_remtime(timer);
208220 ovalue->it_interval
209
- = ktime_to_timeval(tsk->signal->it_real_incr);
221
+ = ktime_to_timespec64(tsk->signal->it_real_incr);
210222 }
211223 /* We are sharing ->siglock with it_real_fn() */
212224 if (hrtimer_try_to_cancel(timer) < 0) {
213225 spin_unlock_irq(&tsk->sighand->siglock);
226
+ hrtimer_cancel_wait_running(timer);
214227 goto again;
215228 }
216
- expires = timeval_to_ktime(value->it_value);
229
+ expires = timespec64_to_ktime(value->it_value);
217230 if (expires != 0) {
218231 tsk->signal->it_real_incr =
219
- timeval_to_ktime(value->it_interval);
232
+ timespec64_to_ktime(value->it_interval);
220233 hrtimer_start(timer, expires, HRTIMER_MODE_REL);
221234 } else
222235 tsk->signal->it_real_incr = 0;
....@@ -236,6 +249,17 @@
236249 return 0;
237250 }
238251
252
+#ifdef CONFIG_SECURITY_SELINUX
253
+void clear_itimer(void)
254
+{
255
+ struct itimerspec64 v = {};
256
+ int i;
257
+
258
+ for (i = 0; i < 3; i++)
259
+ do_setitimer(i, &v, NULL);
260
+}
261
+#endif
262
+
239263 #ifdef __ARCH_WANT_SYS_ALARM
240264
241265 /**
....@@ -252,15 +276,15 @@
252276 */
253277 static unsigned int alarm_setitimer(unsigned int seconds)
254278 {
255
- struct itimerval it_new, it_old;
279
+ struct itimerspec64 it_new, it_old;
256280
257281 #if BITS_PER_LONG < 64
258282 if (seconds > INT_MAX)
259283 seconds = INT_MAX;
260284 #endif
261285 it_new.it_value.tv_sec = seconds;
262
- it_new.it_value.tv_usec = 0;
263
- it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
286
+ it_new.it_value.tv_nsec = 0;
287
+ it_new.it_interval.tv_sec = it_new.it_interval.tv_nsec = 0;
264288
265289 do_setitimer(ITIMER_REAL, &it_new, &it_old);
266290
....@@ -268,8 +292,8 @@
268292 * We can't return 0 if we have an alarm pending ... And we'd
269293 * better return too much than too little anyway
270294 */
271
- if ((!it_old.it_value.tv_sec && it_old.it_value.tv_usec) ||
272
- it_old.it_value.tv_usec >= 500000)
295
+ if ((!it_old.it_value.tv_sec && it_old.it_value.tv_nsec) ||
296
+ it_old.it_value.tv_nsec >= (NSEC_PER_SEC / 2))
273297 it_old.it_value.tv_sec++;
274298
275299 return it_old.it_value.tv_sec;
....@@ -286,15 +310,35 @@
286310
287311 #endif
288312
289
-SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value,
290
- struct itimerval __user *, ovalue)
313
+static int get_itimerval(struct itimerspec64 *o, const struct __kernel_old_itimerval __user *i)
291314 {
292
- struct itimerval set_buffer, get_buffer;
315
+ struct __kernel_old_itimerval v;
316
+
317
+ if (copy_from_user(&v, i, sizeof(struct __kernel_old_itimerval)))
318
+ return -EFAULT;
319
+
320
+ /* Validate the timevals in value. */
321
+ if (!timeval_valid(&v.it_value) ||
322
+ !timeval_valid(&v.it_interval))
323
+ return -EINVAL;
324
+
325
+ o->it_interval.tv_sec = v.it_interval.tv_sec;
326
+ o->it_interval.tv_nsec = v.it_interval.tv_usec * NSEC_PER_USEC;
327
+ o->it_value.tv_sec = v.it_value.tv_sec;
328
+ o->it_value.tv_nsec = v.it_value.tv_usec * NSEC_PER_USEC;
329
+ return 0;
330
+}
331
+
332
+SYSCALL_DEFINE3(setitimer, int, which, struct __kernel_old_itimerval __user *, value,
333
+ struct __kernel_old_itimerval __user *, ovalue)
334
+{
335
+ struct itimerspec64 set_buffer, get_buffer;
293336 int error;
294337
295338 if (value) {
296
- if(copy_from_user(&set_buffer, value, sizeof(set_buffer)))
297
- return -EFAULT;
339
+ error = get_itimerval(&set_buffer, value);
340
+ if (error)
341
+ return error;
298342 } else {
299343 memset(&set_buffer, 0, sizeof(set_buffer));
300344 printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer."
....@@ -306,30 +350,53 @@
306350 if (error || !ovalue)
307351 return error;
308352
309
- if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer)))
353
+ if (put_itimerval(ovalue, &get_buffer))
310354 return -EFAULT;
311355 return 0;
312356 }
313357
314
-#ifdef CONFIG_COMPAT
315
-COMPAT_SYSCALL_DEFINE3(setitimer, int, which,
316
- struct compat_itimerval __user *, in,
317
- struct compat_itimerval __user *, out)
358
+#if defined(CONFIG_COMPAT) || defined(CONFIG_ALPHA)
359
+static int get_old_itimerval32(struct itimerspec64 *o, const struct old_itimerval32 __user *i)
318360 {
319
- struct itimerval kin, kout;
361
+ struct old_itimerval32 v32;
362
+
363
+ if (copy_from_user(&v32, i, sizeof(struct old_itimerval32)))
364
+ return -EFAULT;
365
+
366
+ /* Validate the timevals in value. */
367
+ if (!timeval_valid(&v32.it_value) ||
368
+ !timeval_valid(&v32.it_interval))
369
+ return -EINVAL;
370
+
371
+ o->it_interval.tv_sec = v32.it_interval.tv_sec;
372
+ o->it_interval.tv_nsec = v32.it_interval.tv_usec * NSEC_PER_USEC;
373
+ o->it_value.tv_sec = v32.it_value.tv_sec;
374
+ o->it_value.tv_nsec = v32.it_value.tv_usec * NSEC_PER_USEC;
375
+ return 0;
376
+}
377
+
378
+COMPAT_SYSCALL_DEFINE3(setitimer, int, which,
379
+ struct old_itimerval32 __user *, value,
380
+ struct old_itimerval32 __user *, ovalue)
381
+{
382
+ struct itimerspec64 set_buffer, get_buffer;
320383 int error;
321384
322
- if (in) {
323
- if (get_compat_itimerval(&kin, in))
324
- return -EFAULT;
385
+ if (value) {
386
+ error = get_old_itimerval32(&set_buffer, value);
387
+ if (error)
388
+ return error;
325389 } else {
326
- memset(&kin, 0, sizeof(kin));
390
+ memset(&set_buffer, 0, sizeof(set_buffer));
391
+ printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer."
392
+ " Misfeature support will be removed\n",
393
+ current->comm);
327394 }
328395
329
- error = do_setitimer(which, &kin, out ? &kout : NULL);
330
- if (error || !out)
396
+ error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL);
397
+ if (error || !ovalue)
331398 return error;
332
- if (put_compat_itimerval(out, &kout))
399
+ if (put_old_itimerval32(ovalue, &get_buffer))
333400 return -EFAULT;
334401 return 0;
335402 }