LCOV - code coverage report
Current view: top level - kernel/time - itimer.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 122 0.0 %
Date: 2023-08-24 13:40:31 Functions: 0 14 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (C) 1992 Darren Senn
       4             :  */
       5             : 
       6             : /* These are all the functions necessary to implement itimers */
       7             : 
       8             : #include <linux/mm.h>
       9             : #include <linux/interrupt.h>
      10             : #include <linux/syscalls.h>
      11             : #include <linux/time.h>
      12             : #include <linux/sched/signal.h>
      13             : #include <linux/sched/cputime.h>
      14             : #include <linux/posix-timers.h>
      15             : #include <linux/hrtimer.h>
      16             : #include <trace/events/timer.h>
      17             : #include <linux/compat.h>
      18             : 
      19             : #include <linux/uaccess.h>
      20             : 
      21             : /**
      22             :  * itimer_get_remtime - get remaining time for the timer
      23             :  *
      24             :  * @timer: the timer to read
      25             :  *
      26             :  * Returns the delta between the expiry time and now, which can be
      27             :  * less than zero or 1usec for an pending expired timer
      28             :  */
      29           0 : static struct timespec64 itimer_get_remtime(struct hrtimer *timer)
      30             : {
      31           0 :         ktime_t rem = __hrtimer_get_remaining(timer, true);
      32             : 
      33             :         /*
      34             :          * Racy but safe: if the itimer expires after the above
      35             :          * hrtimer_get_remtime() call but before this condition
      36             :          * then we return 0 - which is correct.
      37             :          */
      38           0 :         if (hrtimer_active(timer)) {
      39           0 :                 if (rem <= 0)
      40           0 :                         rem = NSEC_PER_USEC;
      41             :         } else
      42             :                 rem = 0;
      43             : 
      44           0 :         return ktime_to_timespec64(rem);
      45             : }
      46             : 
      47           0 : static void get_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
      48             :                            struct itimerspec64 *const value)
      49             : {
      50             :         u64 val, interval;
      51           0 :         struct cpu_itimer *it = &tsk->signal->it[clock_id];
      52             : 
      53           0 :         spin_lock_irq(&tsk->sighand->siglock);
      54             : 
      55           0 :         val = it->expires;
      56           0 :         interval = it->incr;
      57           0 :         if (val) {
      58             :                 u64 t, samples[CPUCLOCK_MAX];
      59             : 
      60           0 :                 thread_group_sample_cputime(tsk, samples);
      61           0 :                 t = samples[clock_id];
      62             : 
      63           0 :                 if (val < t)
      64             :                         /* about to fire */
      65             :                         val = TICK_NSEC;
      66             :                 else
      67           0 :                         val -= t;
      68             :         }
      69             : 
      70           0 :         spin_unlock_irq(&tsk->sighand->siglock);
      71             : 
      72           0 :         value->it_value = ns_to_timespec64(val);
      73           0 :         value->it_interval = ns_to_timespec64(interval);
      74           0 : }
      75             : 
      76           0 : static int do_getitimer(int which, struct itimerspec64 *value)
      77             : {
      78           0 :         struct task_struct *tsk = current;
      79             : 
      80           0 :         switch (which) {
      81             :         case ITIMER_REAL:
      82           0 :                 spin_lock_irq(&tsk->sighand->siglock);
      83           0 :                 value->it_value = itimer_get_remtime(&tsk->signal->real_timer);
      84           0 :                 value->it_interval =
      85           0 :                         ktime_to_timespec64(tsk->signal->it_real_incr);
      86           0 :                 spin_unlock_irq(&tsk->sighand->siglock);
      87             :                 break;
      88             :         case ITIMER_VIRTUAL:
      89           0 :                 get_cpu_itimer(tsk, CPUCLOCK_VIRT, value);
      90           0 :                 break;
      91             :         case ITIMER_PROF:
      92           0 :                 get_cpu_itimer(tsk, CPUCLOCK_PROF, value);
      93           0 :                 break;
      94             :         default:
      95             :                 return(-EINVAL);
      96             :         }
      97             :         return 0;
      98             : }
      99             : 
     100           0 : static int put_itimerval(struct __kernel_old_itimerval __user *o,
     101             :                          const struct itimerspec64 *i)
     102             : {
     103             :         struct __kernel_old_itimerval v;
     104             : 
     105           0 :         v.it_interval.tv_sec = i->it_interval.tv_sec;
     106           0 :         v.it_interval.tv_usec = i->it_interval.tv_nsec / NSEC_PER_USEC;
     107           0 :         v.it_value.tv_sec = i->it_value.tv_sec;
     108           0 :         v.it_value.tv_usec = i->it_value.tv_nsec / NSEC_PER_USEC;
     109           0 :         return copy_to_user(o, &v, sizeof(struct __kernel_old_itimerval)) ? -EFAULT : 0;
     110             : }
     111             : 
     112             : 
     113           0 : SYSCALL_DEFINE2(getitimer, int, which, struct __kernel_old_itimerval __user *, value)
     114             : {
     115             :         struct itimerspec64 get_buffer;
     116           0 :         int error = do_getitimer(which, &get_buffer);
     117             : 
     118           0 :         if (!error && put_itimerval(value, &get_buffer))
     119           0 :                 error = -EFAULT;
     120           0 :         return error;
     121             : }
     122             : 
     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             : };
     128             : 
     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))
     148             :                 error = -EFAULT;
     149             :         return error;
     150             : }
     151             : #endif
     152             : 
     153             : /*
     154             :  * The timer is automagically restarted, when interval != 0
     155             :  */
     156           0 : enum hrtimer_restart it_real_fn(struct hrtimer *timer)
     157             : {
     158           0 :         struct signal_struct *sig =
     159           0 :                 container_of(timer, struct signal_struct, real_timer);
     160           0 :         struct pid *leader_pid = sig->pids[PIDTYPE_TGID];
     161             : 
     162           0 :         trace_itimer_expire(ITIMER_REAL, leader_pid, 0);
     163           0 :         kill_pid_info(SIGALRM, SEND_SIG_PRIV, leader_pid);
     164             : 
     165           0 :         return HRTIMER_NORESTART;
     166             : }
     167             : 
     168           0 : static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
     169             :                            const struct itimerspec64 *const value,
     170             :                            struct itimerspec64 *const ovalue)
     171             : {
     172             :         u64 oval, nval, ointerval, ninterval;
     173           0 :         struct cpu_itimer *it = &tsk->signal->it[clock_id];
     174             : 
     175           0 :         nval = timespec64_to_ns(&value->it_value);
     176           0 :         ninterval = timespec64_to_ns(&value->it_interval);
     177             : 
     178           0 :         spin_lock_irq(&tsk->sighand->siglock);
     179             : 
     180           0 :         oval = it->expires;
     181           0 :         ointerval = it->incr;
     182           0 :         if (oval || nval) {
     183           0 :                 if (nval > 0)
     184           0 :                         nval += TICK_NSEC;
     185           0 :                 set_process_cpu_timer(tsk, clock_id, &nval, &oval);
     186             :         }
     187           0 :         it->expires = nval;
     188           0 :         it->incr = ninterval;
     189           0 :         trace_itimer_state(clock_id == CPUCLOCK_VIRT ?
     190             :                            ITIMER_VIRTUAL : ITIMER_PROF, value, nval);
     191             : 
     192           0 :         spin_unlock_irq(&tsk->sighand->siglock);
     193             : 
     194           0 :         if (ovalue) {
     195           0 :                 ovalue->it_value = ns_to_timespec64(oval);
     196           0 :                 ovalue->it_interval = ns_to_timespec64(ointerval);
     197             :         }
     198           0 : }
     199             : 
     200             : /*
     201             :  * Returns true if the timeval is in canonical form
     202             :  */
     203             : #define timeval_valid(t) \
     204             :         (((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
     205             : 
     206           0 : static int do_setitimer(int which, struct itimerspec64 *value,
     207             :                         struct itimerspec64 *ovalue)
     208             : {
     209           0 :         struct task_struct *tsk = current;
     210             :         struct hrtimer *timer;
     211             :         ktime_t expires;
     212             : 
     213           0 :         switch (which) {
     214             :         case ITIMER_REAL:
     215             : again:
     216           0 :                 spin_lock_irq(&tsk->sighand->siglock);
     217           0 :                 timer = &tsk->signal->real_timer;
     218           0 :                 if (ovalue) {
     219           0 :                         ovalue->it_value = itimer_get_remtime(timer);
     220             :                         ovalue->it_interval
     221           0 :                                 = ktime_to_timespec64(tsk->signal->it_real_incr);
     222             :                 }
     223             :                 /* We are sharing ->siglock with it_real_fn() */
     224           0 :                 if (hrtimer_try_to_cancel(timer) < 0) {
     225           0 :                         spin_unlock_irq(&tsk->sighand->siglock);
     226           0 :                         hrtimer_cancel_wait_running(timer);
     227             :                         goto again;
     228             :                 }
     229           0 :                 expires = timespec64_to_ktime(value->it_value);
     230           0 :                 if (expires != 0) {
     231           0 :                         tsk->signal->it_real_incr =
     232             :                                 timespec64_to_ktime(value->it_interval);
     233             :                         hrtimer_start(timer, expires, HRTIMER_MODE_REL);
     234             :                 } else
     235           0 :                         tsk->signal->it_real_incr = 0;
     236             : 
     237           0 :                 trace_itimer_state(ITIMER_REAL, value, 0);
     238           0 :                 spin_unlock_irq(&tsk->sighand->siglock);
     239             :                 break;
     240             :         case ITIMER_VIRTUAL:
     241           0 :                 set_cpu_itimer(tsk, CPUCLOCK_VIRT, value, ovalue);
     242           0 :                 break;
     243             :         case ITIMER_PROF:
     244           0 :                 set_cpu_itimer(tsk, CPUCLOCK_PROF, value, ovalue);
     245           0 :                 break;
     246             :         default:
     247             :                 return -EINVAL;
     248             :         }
     249             :         return 0;
     250             : }
     251             : 
     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             : 
     263             : #ifdef __ARCH_WANT_SYS_ALARM
     264             : 
     265             : /**
     266             :  * alarm_setitimer - set alarm in seconds
     267             :  *
     268             :  * @seconds:    number of seconds until alarm
     269             :  *              0 disables the alarm
     270             :  *
     271             :  * Returns the remaining time in seconds of a pending timer or 0 when
     272             :  * the timer is not active.
     273             :  *
     274             :  * On 32 bit machines the seconds value is limited to (INT_MAX/2) to avoid
     275             :  * negative timeval settings which would cause immediate expiry.
     276             :  */
     277           0 : static unsigned int alarm_setitimer(unsigned int seconds)
     278             : {
     279             :         struct itimerspec64 it_new, it_old;
     280             : 
     281             : #if BITS_PER_LONG < 64
     282             :         if (seconds > INT_MAX)
     283             :                 seconds = INT_MAX;
     284             : #endif
     285           0 :         it_new.it_value.tv_sec = seconds;
     286           0 :         it_new.it_value.tv_nsec = 0;
     287           0 :         it_new.it_interval.tv_sec = it_new.it_interval.tv_nsec = 0;
     288             : 
     289           0 :         do_setitimer(ITIMER_REAL, &it_new, &it_old);
     290             : 
     291             :         /*
     292             :          * We can't return 0 if we have an alarm pending ...  And we'd
     293             :          * better return too much than too little anyway
     294             :          */
     295           0 :         if ((!it_old.it_value.tv_sec && it_old.it_value.tv_nsec) ||
     296           0 :               it_old.it_value.tv_nsec >= (NSEC_PER_SEC / 2))
     297           0 :                 it_old.it_value.tv_sec++;
     298             : 
     299           0 :         return it_old.it_value.tv_sec;
     300             : }
     301             : 
     302             : /*
     303             :  * For backwards compatibility?  This can be done in libc so Alpha
     304             :  * and all newer ports shouldn't need it.
     305             :  */
     306           0 : SYSCALL_DEFINE1(alarm, unsigned int, seconds)
     307             : {
     308           0 :         return alarm_setitimer(seconds);
     309             : }
     310             : 
     311             : #endif
     312             : 
     313           0 : static int get_itimerval(struct itimerspec64 *o, const struct __kernel_old_itimerval __user *i)
     314             : {
     315             :         struct __kernel_old_itimerval v;
     316             : 
     317           0 :         if (copy_from_user(&v, i, sizeof(struct __kernel_old_itimerval)))
     318             :                 return -EFAULT;
     319             : 
     320             :         /* Validate the timevals in value. */
     321           0 :         if (!timeval_valid(&v.it_value) ||
     322           0 :             !timeval_valid(&v.it_interval))
     323             :                 return -EINVAL;
     324             : 
     325           0 :         o->it_interval.tv_sec = v.it_interval.tv_sec;
     326           0 :         o->it_interval.tv_nsec = v.it_interval.tv_usec * NSEC_PER_USEC;
     327           0 :         o->it_value.tv_sec = v.it_value.tv_sec;
     328           0 :         o->it_value.tv_nsec = v.it_value.tv_usec * NSEC_PER_USEC;
     329           0 :         return 0;
     330             : }
     331             : 
     332           0 : 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;
     336             :         int error;
     337             : 
     338           0 :         if (value) {
     339           0 :                 error = get_itimerval(&set_buffer, value);
     340           0 :                 if (error)
     341           0 :                         return error;
     342             :         } else {
     343           0 :                 memset(&set_buffer, 0, sizeof(set_buffer));
     344           0 :                 printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer."
     345             :                             " Misfeature support will be removed\n",
     346             :                             current->comm);
     347             :         }
     348             : 
     349           0 :         error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL);
     350           0 :         if (error || !ovalue)
     351           0 :                 return error;
     352             : 
     353           0 :         if (put_itimerval(ovalue, &get_buffer))
     354             :                 return -EFAULT;
     355           0 :         return 0;
     356             : }
     357             : 
     358             : #if defined(CONFIG_COMPAT) || defined(CONFIG_ALPHA)
     359             : static int get_old_itimerval32(struct itimerspec64 *o, const struct old_itimerval32 __user *i)
     360             : {
     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;
     383             :         int error;
     384             : 
     385             :         if (value) {
     386             :                 error = get_old_itimerval32(&set_buffer, value);
     387             :                 if (error)
     388             :                         return error;
     389             :         } else {
     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);
     394             :         }
     395             : 
     396             :         error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL);
     397             :         if (error || !ovalue)
     398             :                 return error;
     399             :         if (put_old_itimerval32(ovalue, &get_buffer))
     400             :                 return -EFAULT;
     401             :         return 0;
     402             : }
     403             : #endif

Generated by: LCOV version 1.14