Skip to content

Commit 13bdf2d

Browse files
committed
Merge tag 'v5.15.213' into 5.15-main
This is the 5.15.213 stable release # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmprLosACgkQONu9yGCS # aT6Nzw//fNHpgo2dLq1ef5b8DuUss+DP47qZ1T5IxO72F7JkOnG/Ye/CWhO1M4OY # rm3BjkCcFAskvjX9/c69g/SkQNbhylxH6q7e1uAZgzCIlC1xLqrywi0hgCeg/0Kz # zGhZpXF759S04NYXWBawf1oKQGi8emrJsVcisDihK2Ma9qmZztGyUwyj24Bh/TXO # NOXTcPPsaSR5JzR0EHOa/PNkCMr4hfOmrD4rx3JADKqtJDX3EjF8rDXOAwYcIsa1 # ws2bxgh8MUNNQbn8eiN9ZHs5DGoF1an4Tgm/bLtOTMtaL82hqvoYUreoTW8yX3AA # EJwT4Q/8609ZEHcEsjq4CM9m3scqYo/ku0R2QyHTiTsMLsHNpEcbsexVpEiaxZMz # doV+Yn0WRp8zgNenikaRcgpRwiWdKN1mfdQ+pN0v/ZJrVdzyRLkPpo55o+d8Arzz # lKNvY6CFCwLVKgI8fYvK7HM7gFXRKeJnrPFuhWsn8KO23LD99nC7QnOkQ8MzVDxa # SDtoU8cX5OKvZr8h2kRDjdu1XOwBpXRva34rX5E6JUy2DlMfHBX2lFHdSomeTHcV # u+mlzMAcRoZHTY+MuqPU8cvUkuu6UwhheBCHcjdEDXgb5VGAlqaIhk53Lp39u1Sx # sPGYfNMo7kgaqKGvcy4+BVm3UVFS5iocA0kHwFmIjnVjC2Q0nVo= # =iI6l # -----END PGP SIGNATURE----- # gpg: Signature made Thu Jul 30 12:59:23 2026 CEST # gpg: using RSA key 647F28654894E3BD457199BE38DBBDC86092693E # gpg: Can't check signature: No public key
2 parents 1382c49 + 6e2fd65 commit 13bdf2d

4 files changed

Lines changed: 144 additions & 88 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0
22
VERSION = 5
33
PATCHLEVEL = 15
4-
SUBLEVEL = 212
4+
SUBLEVEL = 213
55
EXTRAVERSION =
66
NAME = Trick or Treat
77

kernel/exit.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,13 @@ static void __exit_signal(struct task_struct *tsk)
200200
* doing sigqueue_free() if we have SIGQUEUE_PREALLOC signals.
201201
*/
202202
flush_sigqueue(&tsk->pending);
203-
tsk->sighand = NULL;
203+
204+
/*
205+
* Ensure that all preceeding state is visible. Pairs with
206+
* the smp_acquire__after_ctrl_dep() in the sighand == NULL
207+
* path of lock_task_sighand().
208+
*/
209+
smp_store_release(&tsk->sighand, NULL);
204210
spin_unlock(&sighand->siglock);
205211

206212
__cleanup_sighand(sighand);

kernel/signal.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1388,8 +1388,16 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
13881388
rcu_read_lock();
13891389
for (;;) {
13901390
sighand = rcu_dereference(tsk->sighand);
1391-
if (unlikely(sighand == NULL))
1391+
if (unlikely(sighand == NULL)) {
1392+
/*
1393+
* Pairs with the smp_store_release() in
1394+
* __exit_signal(). It ensures that all state
1395+
* modifications to the task preceeding the store are
1396+
* visible to the callers of lock_task_sighand().
1397+
*/
1398+
smp_acquire__after_ctrl_dep();
13921399
break;
1400+
}
13931401

13941402
/*
13951403
* This sighand can be already freed and even reused, but

kernel/time/posix-cpu-timers.c

Lines changed: 127 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,109 @@ static void disarm_timer(struct k_itimer *timer, struct task_struct *p)
455455
trigger_base_recalc_expires(timer, p);
456456
}
457457

458+
/*
459+
* Lookup the task via timer->it.cpu.pid and attempt to lock the task's sighand.
460+
*
461+
* This can race with the reaping of the task:
462+
*
463+
* CPU0 CPU1
464+
*
465+
* // Finds task
466+
* p = pid_task(pid, pid_type); __exit_signal(p)
467+
* lock(p, sighand);
468+
* posix_cpu_timers*_exit();
469+
* sighand = lock_task_sighand(p); unhash_task(p);
470+
* p->sighand = NULL;
471+
* unlock(sighand);
472+
*
473+
* In this case sighand is NULL, which means the task and the associated timer
474+
* queue cannot be longer accessed safely.
475+
*
476+
* __exit_signal() invokes posix_cpu_timers_exit() and if the thread group is
477+
* dead it also invokes posix_cpu_timers_group_exit(). These functions delete
478+
* all pending timers from the related timer queues. The POSIX timers (k_itimer)
479+
* themself are still accessible, but not longer connected to the task.
480+
*
481+
* exec() works slightly differently. The task which exec()'s terminates all
482+
* other threads in the thread group and runs __exit_signal() on them. As the
483+
* thread group is not dead they only clean up the per task timers via
484+
* posix_cpu_timers_exit().
485+
*
486+
* As the TGID on exec() stays the same per process timers stay queued, if they
487+
* are armed. This works without a problem when exec() is done by the thread
488+
* group leader. If a non-leader thread exec()'s this can end up in the
489+
* following scenario:
490+
*
491+
* CPU0 CPU1
492+
* // Returns old leader
493+
* p = pid_task(pid, pid_type); de_thread()
494+
* switch_leader()
495+
* release_task(old leader)
496+
* __exit_signal()
497+
* old_leader->sighand = NULL;
498+
* // Returns NULL
499+
* sighand = lock_task_sighand(p)
500+
*
501+
* That's problematic for several functions:
502+
*
503+
* - posix_cpu_timer_del(): If the timer is still enqueued on the task the
504+
* underlying k_itimer will be freed which results in a UAF in
505+
* run_posix_cpu_timers() or on timerqueue related add/delete operations.
506+
* If the timer is not enqueued, the failure is harmless
507+
*
508+
* - posix_cpu_timer_set(): Independent of the enqueued state that results in a
509+
* transient failure which is user space visible (-ESRCH) for regular posix
510+
* timers. But for the use case in do_cpu_nanosleep() it's the same UAF
511+
* problem just that the timer is allocated on the stack.
512+
*
513+
* - posix_cpu_timer_rearm(): Timer is not enqueued at that point, but this
514+
* silently ignores the rearm request, which is a functional problem as the
515+
* timer wont expire anymore.
516+
*/
517+
static struct task_struct *timer_lock_sighand(struct k_itimer *timer, unsigned long *flags)
518+
{
519+
enum pid_type type = clock_pid_type(timer->it_clock);
520+
struct cpu_timer *ctmr = &timer->it.cpu;
521+
522+
guard(rcu)();
523+
524+
for (;;) {
525+
struct task_struct *t = pid_task(timer->it.cpu.pid, type);
526+
527+
/* Fail if the task cannot be found. */
528+
if (!t)
529+
break;
530+
531+
/* Try to lock the task's sighand */
532+
if (lock_task_sighand(t, flags))
533+
return t;
534+
535+
/*
536+
* The next PID lookup might either fail or return the new
537+
* leader. This is correct for both exit() and exec().
538+
*/
539+
}
540+
541+
/*
542+
* If the timer is still enqueued, warn. There is nothing safe to do
543+
* here as there might be two timers in there which are removed in
544+
* parallel and that will cause more damage than good. This should never
545+
* happen!
546+
*
547+
* Ensure that the stores to the timer and timerqueue are visible:
548+
*
549+
* __exit_signal()
550+
* posix_cpu_timers*_exit()
551+
* write_seqlock(seqlock)
552+
* smp_wmb(); <-------
553+
* __unhash_process() | !pid_task()
554+
* ----> smp_rmb();
555+
* WARN_ON_ONCE(...)
556+
*/
557+
smp_rmb();
558+
WARN_ON_ONCE(ctmr->head || timerqueue_node_queued(&ctmr->node));
559+
return NULL;
560+
}
458561

459562
/*
460563
* Clean up a CPU-clock timer that is about to be destroyed.
@@ -464,29 +567,13 @@ static void disarm_timer(struct k_itimer *timer, struct task_struct *p)
464567
*/
465568
static int posix_cpu_timer_del(struct k_itimer *timer)
466569
{
467-
struct cpu_timer *ctmr = &timer->it.cpu;
468-
struct sighand_struct *sighand;
469570
struct task_struct *p;
470571
unsigned long flags;
471572
int ret = 0;
472573

473-
rcu_read_lock();
474-
p = cpu_timer_task_rcu(timer);
475-
if (!p)
476-
goto out;
574+
p = timer_lock_sighand(timer, &flags);
477575

478-
/*
479-
* Protect against sighand release/switch in exit/exec and process/
480-
* thread timer list entry concurrent read/writes.
481-
*/
482-
sighand = lock_task_sighand(p, &flags);
483-
if (unlikely(sighand == NULL)) {
484-
/*
485-
* This raced with the reaping of the task. The exit cleanup
486-
* should have removed this timer from the timer queue.
487-
*/
488-
WARN_ON_ONCE(ctmr->head || timerqueue_node_queued(&ctmr->node));
489-
} else {
576+
if (likely(p)) {
490577
if (timer->it.cpu.firing)
491578
ret = TIMER_RETRY;
492579
else
@@ -495,10 +582,8 @@ static int posix_cpu_timer_del(struct k_itimer *timer)
495582
unlock_task_sighand(p, &flags);
496583
}
497584

498-
out:
499-
rcu_read_unlock();
500585
if (!ret)
501-
put_pid(ctmr->pid);
586+
put_pid(timer->it.cpu.pid);
502587

503588
return ret;
504589
}
@@ -620,42 +705,24 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
620705
clockid_t clkid = CPUCLOCK_WHICH(timer->it_clock);
621706
u64 old_expires, new_expires, old_incr, val;
622707
struct cpu_timer *ctmr = &timer->it.cpu;
623-
struct sighand_struct *sighand;
624708
struct task_struct *p;
625709
unsigned long flags;
626710
int ret = 0;
627711

628-
rcu_read_lock();
629-
p = cpu_timer_task_rcu(timer);
630-
if (!p) {
631-
/*
632-
* If p has just been reaped, we can no
633-
* longer get any information about it at all.
634-
*/
635-
rcu_read_unlock();
712+
p = timer_lock_sighand(timer, &flags);
713+
/*
714+
* If p has just been reaped, we can no longer get any information about
715+
* it at all.
716+
*/
717+
if (!p)
636718
return -ESRCH;
637-
}
638719

639720
/*
640721
* Use the to_ktime conversion because that clamps the maximum
641722
* value to KTIME_MAX and avoid multiplication overflows.
642723
*/
643724
new_expires = ktime_to_ns(timespec64_to_ktime(new->it_value));
644725

645-
/*
646-
* Protect against sighand release/switch in exit/exec and p->cpu_timers
647-
* and p->signal->cpu_timers read/write in arm_timer()
648-
*/
649-
sighand = lock_task_sighand(p, &flags);
650-
/*
651-
* If p has just been reaped, we can no
652-
* longer get any information about it at all.
653-
*/
654-
if (unlikely(sighand == NULL)) {
655-
rcu_read_unlock();
656-
return -ESRCH;
657-
}
658-
659726
/*
660727
* Disarm any old timer after extracting its expiry time.
661728
*/
@@ -704,6 +771,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
704771
old->it_value.tv_sec = 0;
705772
}
706773
}
774+
old->it_interval = ns_to_timespec64(old_incr);
707775
}
708776

709777
if (unlikely(ret)) {
@@ -714,7 +782,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
714782
* it as an overrun (thanks to bump_cpu_timer above).
715783
*/
716784
unlock_task_sighand(p, &flags);
717-
goto out;
785+
return ret;
718786
}
719787

720788
if (new_expires != 0 && !(timer_flags & TIMER_ABSTIME)) {
@@ -727,11 +795,11 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
727795
* arm the timer (we'll just fake it for timer_gettime).
728796
*/
729797
cpu_timer_setexpires(ctmr, new_expires);
730-
if (new_expires != 0 && val < new_expires) {
798+
if (new_expires != 0 && val < new_expires)
731799
arm_timer(timer, p);
732-
}
800+
else
801+
trigger_base_recalc_expires(timer, p);
733802

734-
unlock_task_sighand(p, &flags);
735803
/*
736804
* Install the new reload setting, and
737805
* set up the signal and overrun bookkeeping.
@@ -748,35 +816,18 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
748816
timer->it_overrun_last = 0;
749817
timer->it_overrun = -1;
750818

751-
if (val >= new_expires) {
752-
if (new_expires != 0) {
753-
/*
754-
* The designated time already passed, so we notify
755-
* immediately, even if the thread never runs to
756-
* accumulate more time on this clock.
757-
*/
758-
cpu_timer_fire(timer);
759-
}
819+
unlock_task_sighand(p, &flags);
760820

821+
if (new_expires && val >= new_expires) {
761822
/*
762-
* Make sure we don't keep around the process wide cputime
763-
* counter or the tick dependency if they are not necessary.
823+
* The designated time already passed, so we notify immediately,
824+
* even if the thread never runs to accumulate more time on this
825+
* clock.
764826
*/
765-
sighand = lock_task_sighand(p, &flags);
766-
if (!sighand)
767-
goto out;
768-
769-
if (!cpu_timer_queued(ctmr))
770-
trigger_base_recalc_expires(timer, p);
771-
772-
unlock_task_sighand(p, &flags);
827+
cpu_timer_fire(timer);
773828
}
774-
out:
775-
rcu_read_unlock();
776-
if (old)
777-
old->it_interval = ns_to_timespec64(old_incr);
778829

779-
return ret;
830+
return 0;
780831
}
781832

782833
static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec64 *itp)
@@ -1042,19 +1093,12 @@ static void posix_cpu_timer_rearm(struct k_itimer *timer)
10421093
{
10431094
clockid_t clkid = CPUCLOCK_WHICH(timer->it_clock);
10441095
struct task_struct *p;
1045-
struct sighand_struct *sighand;
10461096
unsigned long flags;
10471097
u64 now;
10481098

1049-
rcu_read_lock();
1050-
p = cpu_timer_task_rcu(timer);
1051-
if (!p)
1052-
goto out;
1053-
1054-
/* Protect timer list r/w in arm_timer() */
1055-
sighand = lock_task_sighand(p, &flags);
1056-
if (unlikely(sighand == NULL))
1057-
goto out;
1099+
p = timer_lock_sighand(timer, &flags);
1100+
if (unlikely(!p))
1101+
return;
10581102

10591103
/*
10601104
* Fetch the current sample and update the timer's expiry time.
@@ -1071,8 +1115,6 @@ static void posix_cpu_timer_rearm(struct k_itimer *timer)
10711115
*/
10721116
arm_timer(timer, p);
10731117
unlock_task_sighand(p, &flags);
1074-
out:
1075-
rcu_read_unlock();
10761118
}
10771119

10781120
/**

0 commit comments

Comments
 (0)