Skip to content

[Deepin-Kernel-SIG] [linux 6.6.y] [Upstream] Update kernel base to 6.6.147 - #2034

Merged
opsiff merged 2 commits into
deepin-community:linux-6.6.yfrom
opsiff:linux-stable-update-6.6.147
Jul 31, 2026
Merged

[Deepin-Kernel-SIG] [linux 6.6.y] [Upstream] Update kernel base to 6.6.147#2034
opsiff merged 2 commits into
deepin-community:linux-6.6.yfrom
opsiff:linux-stable-update-6.6.147

Conversation

@opsiff

@opsiff opsiff commented Jul 31, 2026

Copy link
Copy Markdown
Member

Update kernel base to 6.6.147.

Summary by Sourcery

Update POSIX CPU timer handling and signal-hand locking to fix race conditions with task exit/exec, and bump the kernel version to 6.6.147.

Bug Fixes:

  • Prevent use-after-free and missed rearm scenarios in POSIX CPU timer operations when tasks exit or exec by introducing safer task lookup and sighand locking.
  • Ensure correct visibility of task state changes when sighand is cleared during task exit through tightened memory ordering between exit and signal-hand locking paths.

Enhancements:

  • Refactor POSIX CPU timer delete, set, and rearm paths to share a common helper for task lookup and sighand locking and to simplify expiry and firing logic.

Build:

  • Update kernel SUBLEVEL in the top-level Makefile from 146 to 147.

Thomas Gleixner and others added 2 commits July 31, 2026 16:26
commit 920f893 upstream.

Wongi and Jungwoo decoded and reported a non-leader exec() related race
which can result in an UAF:

 sys_timer_delete()			exec()
   posix_cpu_timer_del()
   // Observes old leader
   p = pid_task(pid, pid_type);		de_thread()
   					  switch_leader();
					  release_task(old_leader)
					    __exit_signal(old_leader)
					      sighand = lock(old_leader, sighand);
					      posix_cpu_timers*_exit();
   sighand = lock_task_sighand(p)	      unhash_task(old_leader);
     sh = lock(p, sighand)	    	      old_leader->sighand = NULL;
					      unlock(sighand);
     (p->sighand == NULL)
	unlock(sh)
	return NULL;

   // Returns without action
   if(!sighand)
      return 0;
   free_posix_timer();

This is "harmless" unless the deleted timer was armed and enqueued in
p->signal because on exec() a TGID targeted timer is inherited.

As sys_timer_delete() freed the underlying posix timer object
run_posix_cpu_timers() or any timerqueue related add/delete operations on
other timers will access the freed object's timerqueue node, which results
in an UAF.

There is a similar problem vs. posix_cpu_timer_set(). For regular posix
timers it just transiently returns -ESRCH to user space, but for the use
case in do_cpu_nanosleep() it's the same UAF just that the k_itimer is
allocated on the stack.

Also posix_cpu_timer_rearm() fails to rearm the timer, which means it stops
to expire.

While debating solutions Frederic pointed out another problem:

   posix_cpu_timer_del(tmr)
					__exit_signal(p)
					  posix_cpu_timers*_exit(p);
					  unhash_task(p);
					  p->sighand = NULL;
     sh = lock_task_sighand(p)
        sighand = p->sighand;
	if (!sighand)
	    return NULL;
	lock(sighand);

     if (!sh)
	WARN_ON_ONCE(timer_queued(tmr));

On weakly ordered architectures it is not guaranteed that
posix_cpu_timer_del() will observe the stores in posix_cpu_timers*_exit()
when p->sighand is observed as NULL, which means the WARN() can be a false
positive.

Solve these issues by:

  1) Changing the store in __exit_signal() to smp_store_release().

  2) Adding a smp_acquire__after_ctrl_dep() into the !sighand path
     of lock_task_sighand().

  3) Creating a helper function for looking up the task and locking sighand
     which does not return when sighand == NULL. Instead it retries the
     task lookup and only if that fails it gives up.

  4) Using that helper in the three affected functions.

#1/#2 ensures that the reader side which observes sighand == NULL also
observes all preceeding stores, i.e. the stores in posix_cpu_timers*_exit()
and the ones in unhash_task().

#3 ensures that the above described non-leader exec() situation is handled
gracefully. When the task lookup returns the old leader, but sighand ==
NULL then it retries. In the non-leader exec() case the subsequent task
lookup will observe the new leader due to #1/#2. In normal exit() scenarios
the subsequent lookup fails.

When the task lookup fails, the function also checks whether the timer is
still enqueued and issues a warning if that's the case. Unfortunately there
is nothing which can be done about it, but as the task is already not
longer visible the timer should not be accessed anymore. This check also
requires memory ordering, which is not provided when the first lookup
fails. To achieve that the check is preceeded by a smp_rmb() which pairs
with the smp_wmb() in write_seqlock() in __exit_signal(). That ensures that
the stores in posix_cpu_timers*_exit() are visible.

The history of the non-leader exec() issue goes back to the early days of
posix CPU timers, which stored a pointer to the group leader task in the
timer. That obviously fails when a non-leader exec() switches the leader.
commit e0a7021 ("posix-cpu-timers: workaround to suppress the problems
with mt exec") added a temporary workaround for that in 2010 which survived
about 10 years. The fix for the workaround changed the task pointer to a
pid pointer, but failed to see the subtle race described above. So the
Fixes tag picks that commit, which seems to be halfways accurate.

Thanks to Frederic Weissbecker, Oleg Nesterov and Peter Zijlstra for
review, feedback and suggestions and to Wongi and Jungwoo for the excellent
bug report and analysis!

Fixes: 55e8c8e ("posix-cpu-timers: Store a reference to a pid not a task")
Reported-by: Wongi Lee <qw3rtyp0@gmail.com>
Reported-by: Jungwoo Lee <jwlee2217@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit 12a891c773aeb5823d63dbd0cb2ab931d6c21c9b)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit a1153c0deb44f75190f07677c0c6d61efd887246)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
@sourcery-ai

sourcery-ai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Reviewer's Guide

Updates the kernel base to 6.6.147 and pulls in upstream fixes for POSIX CPU timers, including a new helper for safely locking a task’s sighand under races with exit/exec, memory-ordering corrections around sighand teardown, and minor Makefile version bumps.

Sequence diagram for safe POSIX CPU timer operations racing with task exit

sequenceDiagram
    participant CPU_timer_path
    participant Exit_path
    participant task
    participant sighand

    CPU_timer_path->>CPU_timer_path: posix_cpu_timer_set(timer, timer_flags, new, old)
    CPU_timer_path->>task: timer_lock_sighand(timer, flags)
    activate CPU_timer_path

    par exit_cleanup
        Exit_path->>task: __exit_signal(tsk)
        Exit_path->>sighand: flush_sigqueue(pending)
        Exit_path->>task: smp_store_release_sighand_NULL(&tsk->sighand)
        Exit_path-->>sighand: __cleanup_sighand(sighand)
    and timer_lock
        loop PID retry
            CPU_timer_path->>task: pid_task(timer.it.cpu.pid, clock_pid_type(timer.it_clock))
            alt task found
                CPU_timer_path->>task: lock_task_sighand(tsk, flags)
                alt sighand_non_NULL
                    CPU_timer_path-->>CPU_timer_path: proceed with timer operation
                    CPU_timer_path->>task: unlock_task_sighand(tsk, flags)
                else sighand_NULL
                    CPU_timer_path->>task: smp_acquire__after_ctrl_dep()
                    CPU_timer_path-->>CPU_timer_path: p treated as reaped, return NULL
                end
            else task_not_found
                CPU_timer_path-->>CPU_timer_path: break loop, return NULL
            end
        end
    end

    CPU_timer_path-->>CPU_timer_path: if !p return -ESRCH
    deactivate CPU_timer_path
Loading

File-Level Changes

Change Details Files
Introduce a helper to safely lock a task’s sighand for POSIX CPU timers, handling races with exit/exec and enforcing queue invariants.
  • Add timer_lock_sighand() to look up the target task by pid under RCU, repeatedly try lock_task_sighand(), and return NULL with a warning if the timer remains enqueued after the task vanishes
  • Insert memory barrier and WARN_ON_ONCE checks when the timer appears still queued but the task’s sighand cannot be locked
kernel/time/posix-cpu-timers.c
Refactor POSIX CPU timer operations (delete, set, rearm) to use the new sighand locking helper, simplifying RCU handling and fixing ordering and functional issues.
  • Update posix_cpu_timer_del() to use timer_lock_sighand(), remove explicit RCU locking/unlocking, and ensure pid reference is dropped via timer->it.cpu.pid
  • Update posix_cpu_timer_set() to use timer_lock_sighand(), remove redundant RCU and sighand handling, ensure old->it_interval is always set from old_incr, adjust arm vs trigger_base_recalc_expires logic, and return directly on error
  • Update posix_cpu_timer_rearm() to use timer_lock_sighand(), drop RCU and sighand parameters, and early-return when the task is not found
kernel/time/posix-cpu-timers.c
Fix memory ordering between task exit and sighand locking to avoid races when sighand is set to NULL.
  • Add smp_acquire__after_ctrl_dep() in __lock_task_sighand() when sighand is observed as NULL so prior task state is visible
  • Replace plain assignment to tsk->sighand with smp_store_release(&tsk->sighand, NULL) in __exit_signal() to pair with the acquire side in sighand locking
kernel/signal.c
kernel/exit.c
Bump the kernel sublevel from 6.6.146 to 6.6.147 to align with the new upstream base version.
  • Update SUBLEVEL in the main Makefile to 147
Makefile

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from opsiff. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@dongert
dongert requested a review from Copilot July 31, 2026 08:31
@opsiff
opsiff merged commit dcac973 into deepin-community:linux-6.6.y Jul 31, 2026
14 of 16 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates this tree to Linux 6.6.147 by bringing in upstream fixes around POSIX CPU timer task lookup/sighand locking (to avoid exit/exec races) and tightening memory ordering when clearing tsk->sighand, plus bumping the kernel sublevel.

Changes:

  • Bump kernel sublevel to 6.6.147.
  • Refactor POSIX CPU timer delete/set/rearm to use a shared helper that safely looks up the target task and locks its sighand.
  • Add release/acquire pairing between __exit_signal() and lock_task_sighand() for correct state visibility when sighand becomes NULL.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
Makefile Bumps SUBLEVEL from 146 to 147.
kernel/time/posix-cpu-timers.c Introduces timer_lock_sighand() and updates delete/set/rearm paths to use it, addressing exit/exec races.
kernel/signal.c Adds acquire barrier on the sighand == NULL path in __lock_task_sighand().
kernel/exit.c Switches tsk->sighand = NULL to smp_store_release() to pair with the new acquire path.
Suppressed comments (2)

kernel/time/posix-cpu-timers.c:485

  • Typo/grammar in comment: "themself" / "not longer" -> "themselves" / "no longer".
 * all pending timers from the related timer queues. The POSIX timers (k_itimer)
 * themself are still accessible, but not longer connected to the task.

kernel/time/posix-cpu-timers.c:521

  • Typo in comment: "wont" should be "won't".
 *    timer wont expire anymore.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +479 to +480
* In this case sighand is NULL, which means the task and the associated timer
* queue cannot be longer accessed safely.
Comment thread kernel/signal.c
Comment on lines +1412 to +1417
/*
* Pairs with the smp_store_release() in
* __exit_signal(). It ensures that all state
* modifications to the task preceeding the store are
* visible to the callers of lock_task_sighand().
*/
Comment thread kernel/exit.c
Comment on lines +211 to +215
/*
* Ensure that all preceeding state is visible. Pairs with
* the smp_acquire__after_ctrl_dep() in the sighand == NULL
* path of lock_task_sighand().
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants