Re: [PATCH 20/23] y2038: move itimer reset into itimer.c

From: Ondrej Mosnacek
Date: Sat Nov 09 2019 - 08:43:27 EST


On Fri, Nov 8, 2019 at 10:18 PM Arnd Bergmann <arnd@xxxxxxxx> wrote:
> Preparing for a change to the itimer internals, stop using the
> do_setitimer() symbol and instead use a new higher-level interface.
>
> The do_getitimer()/do_setitimer functions can now be made static,
> allowing the compiler to potentially produce better object code.
>
> Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx>
> ---
> include/linux/time.h | 9 +++++----
> kernel/time/itimer.c | 15 +++++++++++++--
> security/selinux/hooks.c | 10 +++-------
> 3 files changed, 21 insertions(+), 13 deletions(-)
>
> diff --git a/include/linux/time.h b/include/linux/time.h
> index 27d83fd2ae61..0760a4f5a15c 100644
> --- a/include/linux/time.h
> +++ b/include/linux/time.h
> @@ -35,10 +35,11 @@ extern time64_t mktime64(const unsigned int year, const unsigned int mon,
> extern u32 (*arch_gettimeoffset)(void);
> #endif
>
> -struct itimerval;
> -extern int do_setitimer(int which, struct itimerval *value,
> - struct itimerval *ovalue);
> -extern int do_getitimer(int which, struct itimerval *value);
> +#ifdef CONFIG_POSIX_TIMERS
> +extern void clear_itimer(void);
> +#else
> +static inline void clear_itimer(void) {}
> +#endif
>
> extern long do_utimes(int dfd, const char __user *filename, struct timespec64 *times, int flags);
>
> diff --git a/kernel/time/itimer.c b/kernel/time/itimer.c
> index 4664c6addf69..ce9cd19ce72e 100644
> --- a/kernel/time/itimer.c
> +++ b/kernel/time/itimer.c
> @@ -73,7 +73,7 @@ static void get_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
> value->it_interval = ns_to_timeval(interval);
> }
>
> -int do_getitimer(int which, struct itimerval *value)
> +static int do_getitimer(int which, struct itimerval *value)
> {
> struct task_struct *tsk = current;
>
> @@ -197,7 +197,7 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
> #define timeval_valid(t) \
> (((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
>
> -int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
> +static int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
> {
> struct task_struct *tsk = current;
> struct hrtimer *timer;
> @@ -249,6 +249,17 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
> return 0;
> }
>
> +#ifdef CONFIG_SECURITY_SELINUX

Did you mean "#ifdef CONFIG_POSIX_TIMERS" here to match the header?

> +void clear_itimer(void)
> +{
> + struct itimerval v = {};
> + int i;
> +
> + for (i = 0; i < 3; i++)
> + do_setitimer(i, &v, NULL);
> +}
> +#endif
> +
> #ifdef __ARCH_WANT_SYS_ALARM
>
> /**
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 9625b99e677f..c3f2e89acb87 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2549,9 +2549,8 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
> static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
> {
> const struct task_security_struct *tsec = selinux_cred(current_cred());
> - struct itimerval itimer;
> u32 osid, sid;
> - int rc, i;
> + int rc;
>
> osid = tsec->osid;
> sid = tsec->sid;
> @@ -2569,11 +2568,8 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
> rc = avc_has_perm(&selinux_state,
> osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
> if (rc) {
> - if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
> - memset(&itimer, 0, sizeof itimer);
> - for (i = 0; i < 3; i++)
> - do_setitimer(i, &itimer, NULL);
> - }
> + if (IS_ENABLED(CONFIG_POSIX_TIMERS))
> + clear_itimer();

Since you already define a no-op fallback for the case of
!IS_ENABLED(CONFIG_POSIX_TIMERS) in time.h, why not simply call
clear_itimer() unconditionally?

> spin_lock_irq(&current->sighand->siglock);
> if (!fatal_signal_pending(current)) {
> flush_sigqueue(&current->pending);
> --
> 2.20.0
>

--
Ondrej Mosnacek <omosnace at redhat dot com>
Software Engineer, Security Technologies
Red Hat, Inc.