linux-stable/kernel/time
Thomas Gleixner 8dc52c200b posix-timers: Ensure timer ID search-loop limit is valid
[ Upstream commit 8ce8849dd1 ]

posix_timer_add() tries to allocate a posix timer ID by starting from the
cached ID which was stored by the last successful allocation.

This is done in a loop searching the ID space for a free slot one by
one. The loop has to terminate when the search wrapped around to the
starting point.

But that's racy vs. establishing the starting point. That is read out
lockless, which leads to the following problem:

CPU0	  	      	     	   CPU1
posix_timer_add()
  start = sig->posix_timer_id;
  lock(hash_lock);
  ...				   posix_timer_add()
  if (++sig->posix_timer_id < 0)
      			             start = sig->posix_timer_id;
     sig->posix_timer_id = 0;

So CPU1 can observe a negative start value, i.e. -1, and the loop break
never happens because the condition can never be true:

  if (sig->posix_timer_id == start)
     break;

While this is unlikely to ever turn into an endless loop as the ID space is
huge (INT_MAX), the racy read of the start value caught the attention of
KCSAN and Dmitry unearthed that incorrectness.

Rewrite it so that all id operations are under the hash lock.

Reported-by: syzbot+5c54bd3eb218bb595aa9@syzkaller.appspotmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Link: https://lore.kernel.org/r/87bkhzdn6g.ffs@tglx
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-08-11 11:33:48 +02:00
..
Kconfig rcu: Remove nohz_full full-system-idle state machine 2017-06-08 18:52:39 -07:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
alarmtimer.c alarmtimer: Prevent starvation by small intervals and SIG_IGN 2023-02-25 11:50:31 +01:00
clockevents.c clockevents: Make clockevents_config() static 2017-03-23 12:14:05 -07:00
clocksource.c clocksource: Prevent double add_timer_on() for watchdog_timer 2020-02-14 16:32:20 -05:00
hrtimer.c timers: Prevent union confusion from unexpected restart_syscall() 2023-03-11 16:26:41 +01:00
itimer.c time: Prevent undefined behaviour in timespec64_to_ns() 2020-11-18 18:27:52 +01:00
jiffies.c jiffies: Revert bogus conversion of NSEC_PER_SEC to TICK_NSEC 2017-03-07 11:03:28 +01:00
ntp.c ntp: Limit TAI-UTC offset 2019-07-31 07:28:27 +02:00
ntp_internal.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
posix-clock.c ptp: fix the race between the release of ptp_clock and cdev 2020-01-04 14:00:12 +01:00
posix-cpu-timers.c kernel, fs: Introduce and use set_restart_fn() and arch_set_restart_data() 2021-03-24 11:05:05 +01:00
posix-stubs.c timers: Prevent union confusion from unexpected restart_syscall() 2023-03-11 16:26:41 +01:00
posix-timers.c posix-timers: Ensure timer ID search-loop limit is valid 2023-08-11 11:33:48 +02:00
posix-timers.h posix-timers: Make forward callback return s64 2018-10-03 17:00:50 -07:00
sched_clock.c timers, sched_clock: Update timeout for clock wrap 2017-03-23 12:30:27 -07:00
test_udelay.c
tick-broadcast-hrtimer.c tick: broadcast-hrtimer: Fix a race in bc_set_next 2019-10-11 18:18:46 +02:00
tick-broadcast.c tick/broadcast: Use for_each_cpu() specially on UP kernels 2018-05-22 18:54:00 +02:00
tick-common.c
tick-internal.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
tick-oneshot.c
tick-sched.c tick/sched: Annotate lockless access to last_jiffies_update 2020-01-23 08:20:35 +01:00
tick-sched.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
time.c time: Make sure jiffies_to_msecs() preserves non-zero time periods 2018-07-03 11:24:56 +02:00
timeconst.bc
timeconv.c
timecounter.c
timekeeping.c timekeeping: Add raw clock fallback for random_get_entropy() 2022-06-25 11:46:38 +02:00
timekeeping.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
timekeeping_debug.c PM / timekeeping: Print debug messages when requested 2017-07-23 00:03:43 +02:00
timekeeping_internal.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
timer.c random32: make prandom_u32() output unpredictable 2020-11-18 18:28:00 +01:00
timer_list.c timer_list: Guard procfs specific code 2019-07-31 07:28:28 +02:00