]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ntsync: Honour caller's time namespace for absolute MONOTONIC timeouts
authorMaoyi Xie <maoyixie.tju@gmail.com>
Thu, 28 May 2026 06:33:11 +0000 (14:33 +0800)
committerThomas Gleixner <tglx@kernel.org>
Tue, 2 Jun 2026 19:05:36 +0000 (21:05 +0200)
ntsync_schedule() takes the absolute timeout from userspace and hands it to
schedule_hrtimeout_range_clock() with HRTIMER_MODE_ABS. For the default
CLOCK_MONOTONIC path, it does not call timens_ktime_to_host() first.

A process inside a CLOCK_MONOTONIC time namespace computes the absolute
timeout in its own clock view. The kernel reads the same value against the
host clock. The two differ by the namespace offset.  The timeout then fires
too early or too late.

Other users of absolute timeouts run the ktime through
timens_ktime_to_host() before starting the hrtimer. ntsync was added later
and missed that step.

/dev/ntsync is mode 0666. Any user inside a time namespace that can
open it is affected. The visible effect is wrong timeout behaviour
for Wine in a container that sets a CLOCK_MONOTONIC offset.

Reproducer: unshare --user --time, set the monotonic offset to -10s,
issue NTSYNC_IOC_WAIT_ANY with a 100 ms absolute MONOTONIC timeout.
The baseline run elapses about 100 ms. The run inside the namespace
elapses about 0 ms.

Apply timens_ktime_to_host() to the parsed timeout when the caller
did not set NTSYNC_WAIT_REALTIME. The helper does nothing in the
initial time namespace, so the fast path is unchanged.

Fixes: b4a7b5fe3f51 ("ntsync: Introduce NTSYNC_IOC_WAIT_ANY.")
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Elizabeth Figura <zfigura@codeweavers.com>
Link: https://patch.msgid.link/20260528063311.3300393-3-maoyixie.tju@gmail.com
drivers/misc/ntsync.c

index 30af282262efbe482278d9788c04c89f0d33677c..02c9d1192812a45ec78dbc2e3c5841c6eb79d6ab 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sched/signal.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/time_namespace.h>
 #include <uapi/linux/ntsync.h>
 
 #define NTSYNC_NAME    "ntsync"
@@ -836,6 +837,8 @@ static int ntsync_schedule(const struct ntsync_q *q, const struct ntsync_wait_ar
 
        if (args->flags & NTSYNC_WAIT_REALTIME)
                clock = CLOCK_REALTIME;
+       else
+               timeout = timens_ktime_to_host(clock, timeout);
 
        do {
                if (signal_pending(current)) {