Re: [PATCH] timekeeping: Require permission to set auxiliary clocks

From: John Stultz

Date: Wed Oct 21 2026 - 14:29:57 EST


On Mon, Oct 19, 2026 at 1:03 AM Daehyeon Ko <4ncienth@xxxxxxxxx> wrote:
>
> The generic clock_settime() entry point delegates permission checks to
> each clock-specific callback. aux_clock_set() does not perform one. Once
> an administrator enables an auxiliary clock, any local process can
> therefore change the global clock offset.
>
> A test process running as UID and GID 65534 with no effective, permitted,
> inheritable, or ambient capabilities set CLOCK_AUX0 successfully, and a
> separate process observed the new value. The same process was denied by
> clock_adjtime(). An AppArmor profile denying sys_time also blocked
> CLOCK_REALTIME changes but did not see the auxiliary clock operation.
>
> Call security_settime64() before mutating the auxiliary timekeeper. This
> matches CLOCK_REALTIME's permission model, enforces initial-user-namespace
> CAP_SYS_TIME, and gives LSMs the settime hook while preserving authorized
> clock changes.
>
> Fixes: 60ecc26ec5af ("timekeeping: Provide time setter for auxiliary clocks")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Daehyeon Ko <4ncienth@xxxxxxxxx>
> ---
> AI assistance was used for source analysis, reproducer development, and
> validation. The submitter reviewed the resulting change before signing it.
>
> kernel/time/timekeeping.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
> index ea2e6e55f37bf..1b342825bd8f1 100644
> --- a/kernel/time/timekeeping.c
> +++ b/kernel/time/timekeeping.c
> @@ -14,6 +14,7 @@
> #include <linux/random.h>
> #include <linux/sched/clock.h>
> #include <linux/sched/loadavg.h>
> +#include <linux/security.h>
> #include <linux/static_key.h>
> #include <linux/stop_machine.h>
> #include <linux/syscore_ops.h>
> @@ -3215,11 +3216,15 @@ static int aux_clock_set(const clockid_t id, const struct timespec64 *tnew)
> struct tk_data *aux_tkd = aux_get_tk_data(id);
> struct timekeeper *aux_tks;
> ktime_t tnow, nsecs;
> + int ret;
>
> if (!timespec64_valid_settod(tnew))
> return -EINVAL;
> if (!aux_tkd)
> return -ENODEV;
> + ret = security_settime64(tnew, NULL);
> + if (ret)
> + return ret;
>
> aux_tks = &aux_tkd->shadow_timekeeper;

This looked a little odd adding the security_settime64() check in the
core timekeeping.c where as is usually called closer to the syscall in
time.c, but given the clock_aux k_clock is defined in timekeeping.c, I
guess this makes it the best place to add the check.

Acked-by: John Stultz <jstultz@xxxxxxxxxx>

thanks
-john