summaryrefslogtreecommitdiff
path: root/kernel/time
diff options
context:
space:
mode:
authorDaehyeon Ko <4ncienth@gmail.com>2026-10-19 17:03:24 +0900
committerThomas Gleixner <tglx@kernel.org>2026-10-23 21:49:57 +0200
commit524d95c8a2000cba6cb80a173d76cb746c561244 (patch)
tree9473ebb38008f2cb1f0a8bd73cf0bbe6d7d235c0 /kernel/time
parent8ccd731b63a0183ca2b0e18f3ca15864b3f37eda (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.c5
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;