diff options
| author | Daehyeon Ko <4ncienth@gmail.com> | 2026-10-19 17:03:24 +0900 |
|---|---|---|
| committer | Thomas Gleixner <tglx@kernel.org> | 2026-10-23 21:49:57 +0200 |
| commit | 524d95c8a2000cba6cb80a173d76cb746c561244 (patch) | |
| tree | 9473ebb38008f2cb1f0a8bd73cf0bbe6d7d235c0 /kernel/time | |
| parent | 8ccd731b63a0183ca2b0e18f3ca15864b3f37eda (diff) | |
timekeeping: Require permission to set auxiliary clocks
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")
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Tested-by: shaos <shawnq1@163.com>
Acked-by: John Stultz <jstultz@google.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261019080324.4147815-1-4ncienth@gmail.com
Diffstat (limited to 'kernel/time')
| -rw-r--r-- | kernel/time/timekeeping.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index ea2e6e55f37b..1b342825bd8f 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; |
