Skip to content

Commit 922ed50

Browse files
committed
Merge tag 'v6.1.180' into 6.1-main
This is the 6.1.180 stable release # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmprLxEACgkQONu9yGCS # aT7+ow/8DO91wKGavgZ8P2cgw5eKymFQ6pwEU++bsG2rKXs0iqsbc6Mvm/XfpNak # nC3M7+z4Hfvzy5+t0VS/2YyderxI9XzEQWa9iwAlheBw7F9qfDN70sAkU54kki1m # sD+uEi3r3EtlWrP2pTpa660DfnyQ1o2Pt8lg8AIBqRzN0HPAGgOhk99zVMsgIijd # VkCSAj6zd5sE8QCihbYVPAXKlZVXIuc2Udkc1hPH6K2WZpOMdMUnKbPSB8DwJYOm # Oy32/YFsfO+h9h0CUTLfrvZzuVXF/Jgiv7W7rYL3Y9i4ptucCybzaOu6Fik+Muae # eJ7jNwCe2NEl6516C224xfnrZ+oA4hysYvCP1B5b9nTp5KO/QzRwdQ69JI9otxch # qgI8jcqf02Ts5mQyrICAKYl+baoNmvtkZ9MQiKuw5tIzt/I9aqxAFo9nFQ5zeoSs # 4bCigSKE7oHPwhxAMn+nffcYRG0i2BTEYugboNLVuhllCZDFy7mlDaet0iub8sJL # KDIbTBxukvvnDNRZ8xNCBTDQUD82Q0zfVHENxt1uU+cnZGST3KXvMOBq+nZWfxE3 # Dg3gfoLrI1dOgpoAp2c0JZsyx7gPtv5gVrcfm90DrfzBBu22afKyVt2fL8XzvGrT # cxcRMe1P46ERwAnjB/likCUHlhD2qDuhA+jtNdcEUEocF4sEhlI= # =QcO5 # -----END PGP SIGNATURE----- # gpg: Signature made Thu Jul 30 13:01:37 2026 CEST # gpg: using RSA key 647F28654894E3BD457199BE38DBBDC86092693E # gpg: Can't check signature: No public key
2 parents abc9a53 + fb28aa7 commit 922ed50

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 = 6
33
PATCHLEVEL = 1
4-
SUBLEVEL = 179
4+
SUBLEVEL = 180
55
EXTRAVERSION =
66
NAME = Curry Ramen
77

kernel/exit.c

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

209215
__cleanup_sighand(sighand);

kernel/signal.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1395,8 +1395,16 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
13951395
rcu_read_lock();
13961396
for (;;) {
13971397
sighand = rcu_dereference(tsk->sighand);
1398-
if (unlikely(sighand == NULL))
1398+
if (unlikely(sighand == NULL)) {
1399+
/*
1400+
* Pairs with the smp_store_release() in
1401+
* __exit_signal(). It ensures that all state
1402+
* modifications to the task preceeding the store are
1403+
* visible to the callers of lock_task_sighand().
1404+
*/
1405+
smp_acquire__after_ctrl_dep();
13991406
break;
1407+
}
14001408

14011409
/*
14021410
* 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
@@ -462,6 +462,109 @@ static void disarm_timer(struct k_itimer *timer, struct task_struct *p)
462462
trigger_base_recalc_expires(timer, p);
463463
}
464464

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

466569
/*
467570
* Clean up a CPU-clock timer that is about to be destroyed.
@@ -471,29 +574,13 @@ static void disarm_timer(struct k_itimer *timer, struct task_struct *p)
471574
*/
472575
static int posix_cpu_timer_del(struct k_itimer *timer)
473576
{
474-
struct cpu_timer *ctmr = &timer->it.cpu;
475-
struct sighand_struct *sighand;
476577
struct task_struct *p;
477578
unsigned long flags;
478579
int ret = 0;
479580

480-
rcu_read_lock();
481-
p = cpu_timer_task_rcu(timer);
482-
if (!p)
483-
goto out;
581+
p = timer_lock_sighand(timer, &flags);
484582

485-
/*
486-
* Protect against sighand release/switch in exit/exec and process/
487-
* thread timer list entry concurrent read/writes.
488-
*/
489-
sighand = lock_task_sighand(p, &flags);
490-
if (unlikely(sighand == NULL)) {
491-
/*
492-
* This raced with the reaping of the task. The exit cleanup
493-
* should have removed this timer from the timer queue.
494-
*/
495-
WARN_ON_ONCE(ctmr->head || timerqueue_node_queued(&ctmr->node));
496-
} else {
583+
if (likely(p)) {
497584
if (timer->it.cpu.firing)
498585
ret = TIMER_RETRY;
499586
else
@@ -502,10 +589,8 @@ static int posix_cpu_timer_del(struct k_itimer *timer)
502589
unlock_task_sighand(p, &flags);
503590
}
504591

505-
out:
506-
rcu_read_unlock();
507592
if (!ret)
508-
put_pid(ctmr->pid);
593+
put_pid(timer->it.cpu.pid);
509594

510595
return ret;
511596
}
@@ -627,42 +712,24 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
627712
clockid_t clkid = CPUCLOCK_WHICH(timer->it_clock);
628713
u64 old_expires, new_expires, old_incr, val;
629714
struct cpu_timer *ctmr = &timer->it.cpu;
630-
struct sighand_struct *sighand;
631715
struct task_struct *p;
632716
unsigned long flags;
633717
int ret = 0;
634718

635-
rcu_read_lock();
636-
p = cpu_timer_task_rcu(timer);
637-
if (!p) {
638-
/*
639-
* If p has just been reaped, we can no
640-
* longer get any information about it at all.
641-
*/
642-
rcu_read_unlock();
719+
p = timer_lock_sighand(timer, &flags);
720+
/*
721+
* If p has just been reaped, we can no longer get any information about
722+
* it at all.
723+
*/
724+
if (!p)
643725
return -ESRCH;
644-
}
645726

646727
/*
647728
* Use the to_ktime conversion because that clamps the maximum
648729
* value to KTIME_MAX and avoid multiplication overflows.
649730
*/
650731
new_expires = ktime_to_ns(timespec64_to_ktime(new->it_value));
651732

652-
/*
653-
* Protect against sighand release/switch in exit/exec and p->cpu_timers
654-
* and p->signal->cpu_timers read/write in arm_timer()
655-
*/
656-
sighand = lock_task_sighand(p, &flags);
657-
/*
658-
* If p has just been reaped, we can no
659-
* longer get any information about it at all.
660-
*/
661-
if (unlikely(sighand == NULL)) {
662-
rcu_read_unlock();
663-
return -ESRCH;
664-
}
665-
666733
/*
667734
* Disarm any old timer after extracting its expiry time.
668735
*/
@@ -711,6 +778,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
711778
old->it_value.tv_sec = 0;
712779
}
713780
}
781+
old->it_interval = ns_to_timespec64(old_incr);
714782
}
715783

716784
if (unlikely(ret)) {
@@ -721,7 +789,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
721789
* it as an overrun (thanks to bump_cpu_timer above).
722790
*/
723791
unlock_task_sighand(p, &flags);
724-
goto out;
792+
return ret;
725793
}
726794

727795
if (new_expires != 0 && !(timer_flags & TIMER_ABSTIME)) {
@@ -734,11 +802,11 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
734802
* arm the timer (we'll just fake it for timer_gettime).
735803
*/
736804
cpu_timer_setexpires(ctmr, new_expires);
737-
if (new_expires != 0 && val < new_expires) {
805+
if (new_expires != 0 && val < new_expires)
738806
arm_timer(timer, p);
739-
}
807+
else
808+
trigger_base_recalc_expires(timer, p);
740809

741-
unlock_task_sighand(p, &flags);
742810
/*
743811
* Install the new reload setting, and
744812
* set up the signal and overrun bookkeeping.
@@ -755,35 +823,18 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
755823
timer->it_overrun_last = 0;
756824
timer->it_overrun = -1;
757825

758-
if (val >= new_expires) {
759-
if (new_expires != 0) {
760-
/*
761-
* The designated time already passed, so we notify
762-
* immediately, even if the thread never runs to
763-
* accumulate more time on this clock.
764-
*/
765-
cpu_timer_fire(timer);
766-
}
826+
unlock_task_sighand(p, &flags);
767827

828+
if (new_expires && val >= new_expires) {
768829
/*
769-
* Make sure we don't keep around the process wide cputime
770-
* counter or the tick dependency if they are not necessary.
830+
* The designated time already passed, so we notify immediately,
831+
* even if the thread never runs to accumulate more time on this
832+
* clock.
771833
*/
772-
sighand = lock_task_sighand(p, &flags);
773-
if (!sighand)
774-
goto out;
775-
776-
if (!cpu_timer_queued(ctmr))
777-
trigger_base_recalc_expires(timer, p);
778-
779-
unlock_task_sighand(p, &flags);
834+
cpu_timer_fire(timer);
780835
}
781-
out:
782-
rcu_read_unlock();
783-
if (old)
784-
old->it_interval = ns_to_timespec64(old_incr);
785836

786-
return ret;
837+
return 0;
787838
}
788839

789840
static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec64 *itp)
@@ -1049,19 +1100,12 @@ static void posix_cpu_timer_rearm(struct k_itimer *timer)
10491100
{
10501101
clockid_t clkid = CPUCLOCK_WHICH(timer->it_clock);
10511102
struct task_struct *p;
1052-
struct sighand_struct *sighand;
10531103
unsigned long flags;
10541104
u64 now;
10551105

1056-
rcu_read_lock();
1057-
p = cpu_timer_task_rcu(timer);
1058-
if (!p)
1059-
goto out;
1060-
1061-
/* Protect timer list r/w in arm_timer() */
1062-
sighand = lock_task_sighand(p, &flags);
1063-
if (unlikely(sighand == NULL))
1064-
goto out;
1106+
p = timer_lock_sighand(timer, &flags);
1107+
if (unlikely(!p))
1108+
return;
10651109

10661110
/*
10671111
* Fetch the current sample and update the timer's expiry time.
@@ -1078,8 +1122,6 @@ static void posix_cpu_timer_rearm(struct k_itimer *timer)
10781122
*/
10791123
arm_timer(timer, p);
10801124
unlock_task_sighand(p, &flags);
1081-
out:
1082-
rcu_read_unlock();
10831125
}
10841126

10851127
/**

0 commit comments

Comments
 (0)