linux/kernel/time
Michael Pratt ca7752caea posix-cpu-timers: Clear task::posix_cputimers_work in copy_process()
copy_process currently copies task_struct.posix_cputimers_work as-is. If a
timer interrupt arrives while handling clone and before dup_task_struct
completes then the child task will have:

1. posix_cputimers_work.scheduled = true
2. posix_cputimers_work.work queued.

copy_process clears task_struct.task_works, so (2) will have no effect and
posix_cpu_timers_work will never run (not to mention it doesn't make sense
for two tasks to share a common linked list).

Since posix_cpu_timers_work never runs, posix_cputimers_work.scheduled is
never cleared. Since scheduled is set, future timer interrupts will skip
scheduling work, with the ultimate result that the task will never receive
timer expirations.

Together, the complete flow is:

1. Task 1 calls clone(), enters kernel.
2. Timer interrupt fires, schedules task work on Task 1.
   2a. task_struct.posix_cputimers_work.scheduled = true
   2b. task_struct.posix_cputimers_work.work added to
       task_struct.task_works.
3. dup_task_struct() copies Task 1 to Task 2.
4. copy_process() clears task_struct.task_works for Task 2.
5. Future timer interrupts on Task 2 see
   task_struct.posix_cputimers_work.scheduled = true and skip scheduling
   work.

Fix this by explicitly clearing contents of task_struct.posix_cputimers_work
in copy_process(). This was never meant to be shared or inherited across
tasks in the first place.

Fixes: 1fb497dd00 ("posix-cpu-timers: Provide mechanisms to defer timer handling to task_work")
Reported-by: Rhys Hiltner <rhys@justin.tv>
Signed-off-by: Michael Pratt <mpratt@google.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20211101210615.716522-1-mpratt@google.com
2021-11-02 12:52:17 +01:00
..
alarmtimer.c alarmtimer: Check RTC features instead of ops 2021-05-11 21:28:04 +02:00
clockevents.c clockevents: Use list_move() instead of list_del()/list_add() 2021-06-22 17:16:46 +02:00
clocksource-wdtest.c clocksource: Make clocksource watchdog test safe for slow-HZ systems 2021-08-28 17:01:32 +02:00
clocksource.c clocksource: Replace deprecated CPU-hotplug functions. 2021-08-10 14:53:58 +02:00
hrtimer.c hrtimer: Unbreak hrtimer_force_reprogram() 2021-08-12 22:34:40 +02:00
itimer.c time: Prevent undefined behaviour in timespec64_to_ns() 2020-10-26 11:48:11 +01:00
jiffies.c clocksource: Make clocksource watchdog test safe for slow-HZ systems 2021-08-28 17:01:32 +02:00
Kconfig -----BEGIN PGP SIGNATURE----- 2021-06-29 12:31:16 -07:00
Makefile time: Improve performance of time64_to_tm() 2021-06-24 11:51:59 +02:00
namespace.c memcg: enable accounting for new namesapces and struct nsproxy 2021-09-03 09:58:12 -07:00
ntp_internal.h ntp: Make the RTC synchronization more reliable 2020-12-11 10:40:52 +01:00
ntp.c timekeeping, clocksource: Fix various typos in comments 2021-03-22 23:06:48 +01:00
posix-clock.c posix-clocks: Rename the clock_get() callback to clock_get_timespec() 2020-01-14 12:20:49 +01:00
posix-cpu-timers.c posix-cpu-timers: Clear task::posix_cputimers_work in copy_process() 2021-11-02 12:52:17 +01:00
posix-stubs.c posix-timers: Make clock_nanosleep() time namespace aware 2020-01-14 12:20:55 +01:00
posix-timers.c Merge branch 'akpm' (patches from Andrew) 2021-09-03 10:08:28 -07:00
posix-timers.h posix-clocks: Introduce clock_get_ktime() callback 2020-01-14 12:20:51 +01:00
sched_clock.c time/sched_clock: Mark sched_clock_read_begin/retry() as notrace 2020-10-26 11:34:31 +01:00
test_udelay.c time/debug: Remove dentry pointer for debugfs 2021-03-18 11:20:26 +01:00
tick-broadcast-hrtimer.c timekeeping, clocksource: Fix various typos in comments 2021-03-22 23:06:48 +01:00
tick-broadcast.c timer_list: Print name of per-cpu wakeup device 2021-05-31 17:04:49 +02:00
tick-common.c timekeeping: Distangle resume and clock-was-set events 2021-08-10 17:57:23 +02:00
tick-internal.h clocksource: Make clocksource watchdog test safe for slow-HZ systems 2021-08-28 17:01:32 +02:00
tick-legacy.c timekeeping: remove xtime_update 2020-10-30 21:57:07 +01:00
tick-oneshot.c timekeeping, clocksource: Fix various typos in comments 2021-03-22 23:06:48 +01:00
tick-sched.c Updates to the tick/nohz code in this cycle: 2021-06-28 12:22:06 -07:00
tick-sched.h timekeeping, clocksource: Fix various typos in comments 2021-03-22 23:06:48 +01:00
time_test.c time/kunit: Add missing MODULE_LICENSE() 2021-06-28 07:40:23 +02:00
time.c timekeeping, clocksource: Fix various typos in comments 2021-03-22 23:06:48 +01:00
timeconst.bc time: Add SPDX license identifiers 2018-11-23 11:51:20 +01:00
timeconv.c time: Improve performance of time64_to_tm() 2021-06-24 11:51:59 +02:00
timecounter.c time/timecounter: Mark 1st argument of timecounter_cyc2time() as const 2021-04-16 21:03:50 +02:00
timekeeping_debug.c timekeeping/debug: No need to check return value of debugfs_create functions 2019-01-29 20:08:41 +01:00
timekeeping_internal.h timekeeping/vsyscall: Provide vdso_update_begin/end() 2020-08-06 10:57:30 +02:00
timekeeping.c hrtimer: Add bases argument to clock_was_set() 2021-08-10 17:57:23 +02:00
timekeeping.h asm-generic: cross-architecture timer cleanup 2020-12-16 00:07:17 -08:00
timer_list.c timer_list: Print name of per-cpu wakeup device 2021-05-31 17:04:49 +02:00
timer.c timers: Move clearing of base::timer_running under base:: Lock 2021-07-27 20:57:44 +02:00
vsyscall.c timekeeping, clocksource: Fix various typos in comments 2021-03-22 23:06:48 +01:00