posix-timers: Ensure that timer initialization is fully visible
authorThomas Gleixner <tglx@linutronix.de>
Sat, 8 Mar 2025 16:48:10 +0000 (17:48 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 13 Mar 2025 11:07:16 +0000 (12:07 +0100)
commit2389c6efd3ad8edb3bcce0019b4edcc7d9c7de19
tree878b2c4e613277409de5b5d4dcfa39b7383456be
parentfc661d0a78673f23a3fd78d0bb20900ee64d1839
posix-timers: Ensure that timer initialization is fully visible

Frederic pointed out that the memory operations to initialize the timer are
not guaranteed to be visible, when __lock_timer() observes timer::it_signal
valid under timer::it_lock:

  T0                                      T1
  ---------                               -----------
  do_timer_create()
      // A
      new_timer->.... = ....
      spin_lock(current->sighand)
      // B
      WRITE_ONCE(new_timer->it_signal, current->signal)
      spin_unlock(current->sighand)
sys_timer_*()
   t =  __lock_timer()
  spin_lock(&timr->it_lock)
  // observes B
  if (timr->it_signal == current->signal)
    return timr;
                   if (!t)
       return;
// Is not guaranteed to observe A

Protect the write of timer::it_signal, which makes the timer valid, with
timer::it_lock as well. This guarantees that T1 must observe the
initialization A completely, when it observes the valid signal pointer
under timer::it_lock. sighand::siglock must still be taken to protect the
signal::posix_timers list.

Reported-by: Frederic Weisbecker <frederic@kernel.org>
Suggested-by: Frederic Weisbecker <frederic@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Link: https://lore.kernel.org/all/20250308155623.507944489@linutronix.de
kernel/time/posix-timers.c