linux-stable/kernel/time
Michael Pratt f67f6eb717 posix-cpu-timers: Clear task::posix_cputimers_work in copy_process()
commit ca7752caea upstream.

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
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-11-18 14:04:29 +01:00
..
alarmtimer.c kernel, fs: Introduce and use set_restart_fn() and arch_set_restart_data() 2021-03-25 09:04:16 +01:00
clockevents.c
clocksource.c clocksource: Check per-CPU clock synchronization when marked unstable 2021-07-14 16:56:01 +02:00
hrtimer.c hrtimer: Ensure timerfd notification for HIGHRES=n 2021-09-15 09:50:25 +02:00
itimer.c time: Prevent undefined behaviour in timespec64_to_ns() 2020-10-26 11:48:11 +01:00
jiffies.c timekeeping: Split jiffies seqlock 2020-03-21 16:00:23 +01:00
Kconfig posix-cpu-timers: Provide mechanisms to defer timer handling to task_work 2020-08-06 16:50:59 +02:00
Makefile ns: Introduce Time Namespace 2020-01-14 12:20:48 +01:00
namespace.c nsproxy: support CLONE_NEWTIME with setns() 2020-07-08 11:14:22 +02:00
ntp.c ntp/y2038: Remove incorrect time_t truncation 2019-11-12 08:13:44 +01:00
ntp_internal.h
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-18 14:04:29 +01:00
posix-stubs.c posix-timers: Make clock_nanosleep() time namespace aware 2020-01-14 12:20:55 +01:00
posix-timers.c posix-timers: Preserve return value in clock_adjtime32() 2021-05-11 14:47:16 +02: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
tick-broadcast-hrtimer.c tick: broadcast-hrtimer: Fix a race in bc_set_next 2019-09-27 14:45:55 +02:00
tick-broadcast.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
tick-common.c timekeeping: Split jiffies seqlock 2020-03-21 16:00:23 +01:00
tick-internal.h hrtimer: Ensure timerfd notification for HIGHRES=n 2021-09-15 09:50:25 +02:00
tick-oneshot.c
tick-sched.c tick/sched: Remove bogus boot "safety" check 2021-01-06 14:56:55 +01:00
tick-sched.h
time.c y2038: remove unused time32 interfaces 2020-02-21 11:22:15 -08:00
timeconst.bc
timeconv.c
timecounter.c
timekeeping.c These are the locking updates for v5.10: 2020-10-12 13:06:20 -07:00
timekeeping.h timekeeping: Split jiffies seqlock 2020-03-21 16:00:23 +01:00
timekeeping_debug.c
timekeeping_internal.h timekeeping/vsyscall: Provide vdso_update_begin/end() 2020-08-06 10:57:30 +02:00
timer.c timers: Move clearing of base::timer_running under base:: Lock 2021-08-12 13:22:15 +02:00
timer_list.c timer_list: Guard procfs specific code 2019-06-23 00:08:52 +02:00
vsyscall.c timekeeping/vsyscall: Provide vdso_update_begin/end() 2020-08-06 10:57:30 +02:00