CVE-2026-53361: af_unix: set gc_in_progress to true in unix_gc()

Adds Patch2013 backporting linux-6.12.y stable commit 591f1ac21742
("af_unix: Set gc_in_progress to true in unix_gc()."), the 6.12 backport
of mainline d82ba05263c6 by Kuniyuki Iwashima.

unix_schedule_gc()/wait_for_unix_gc() only set gc_in_progress before
queueing the GC work, so a second schedule racing an in-flight unix_gc()
could leave gc_in_progress false while GC is still running. unix_peek_fpl()
relies on that flag to avoid confusing GC via MSG_PEEK. The fix sets
gc_in_progress inside __unix_gc() itself.

Verified with --fuzz=0 against both the CentOS Stream 10
kernel-6.12.0-211.el10 tag and the extracted 6.12.0-211.34.1.el10_2 tree:
single hunk in net/unix/garbage.c, no fuzz (offset only), and the WRITE_ONCE
is not already present in __unix_gc(). No overlap with the other patches in
this config, which touch arch/x86/kvm, drivers/scsi, drivers/message/fusion,
drivers/net/ethernet/google and fs/btrfs packaging only.

Drops the previous Patch2013 (CVE-2026-64561, KVM: x86: check for
invalid/obsolete root after making MMU pages available), which was sourced
from the still-Draft CentOS Stream 10 MR 3068; the 2013 slot is reused.
This commit is contained in:
Andrew Lukoshko 2026-08-13 13:40:20 +02:00
parent 048f1efd0c
commit 520e159f6e
3 changed files with 67 additions and 99 deletions

View File

@ -57,7 +57,7 @@ actions:
number: 2012
- type: "patch"
name: "2013-CVE-2026-64561-KVM-x86-Check-for-invalid-obsolete-root.patch"
name: "2013-CVE-2026-53361-af_unix-Set-gc_in_progress-to-true-in-un.patch"
number: 2013
- replace:
@ -470,7 +470,7 @@ actions:
- name: "Andrew Lukoshko"
email: "alukoshko@almalinux.org"
line:
- "KVM: x86: check for invalid/obsolete root after making MMU pages available {CVE-2026-64561}"
- "af_unix: set gc_in_progress to true in unix_gc() {CVE-2026-53361}"
- "hpsa: bring back deprecated PCI ids #CFHack #CFHack2024"
- "mptsas: bring back deprecated PCI ids #CFHack #CFHack2024"
- "megaraid_sas: bring back deprecated PCI ids #CFHack #CFHack2024"

View File

@ -0,0 +1,65 @@
From 591f1ac217428a6d2b32a8ac14aac0fab44f155a Mon Sep 17 00:00:00 2001
From: Kuniyuki Iwashima <kuniyu@google.com>
Date: Wed, 1 Jul 2026 09:53:06 +0300
Subject: [PATCH AlmaLinux 10] af_unix: Set gc_in_progress to true in unix_gc().
CVE: CVE-2026-53361
Backported from the linux-6.12.y stable tree, commit 591f1ac21742
("af_unix: Set gc_in_progress to true in unix_gc()."), which is the
6.12 backport of mainline commit d82ba05263c6.
[ Upstream commit d82ba05263c69fa2437fe93e4e561cc40f4c03af ]
Igor Ushakov reported that unix_gc() could run with gc_in_progress
being false if the work is scheduled while running:
Thread 1 Thread 2 Thread 3
-------- -------- --------
unix_schedule_gc() unix_schedule_gc()
`- if (!gc_in_progress) `- if (!gc_in_progress)
|- gc_in_progress = true |
`- queue_work() |
unix_gc() <----------------/ |
| |- gc_in_progress = true
... `- queue_work()
| |
`- gc_in_progress = false |
|
unix_gc() <---------------------------------------------'
|
... /* gc_in_progress == false */
|
`- gc_in_progress = false
unix_peek_fpl() relies on gc_in_progress not to confuse GC
by MSG_PEEK.
Let's set gc_in_progress to true in unix_gc().
Fixes: 8b90a9f819dc ("af_unix: Run GC on only one CPU.")
Reported-by: Igor Ushakov <sysroot314@gmail.com>
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260501073945.1884564-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Add setting gc_in_progress in __unix_gc(). Keep the existing
set in unix_gc() for wait_for_unix_gc() over-limit throttling. ]
Signed-off-by: Igor Ushakov <sysroot314@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/unix/garbage.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index 1cdb54c61619..fa6983dc3181 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -583,6 +583,8 @@ static void __unix_gc(struct work_struct *work)
struct sk_buff_head hitlist;
struct sk_buff *skb;
+ WRITE_ONCE(gc_in_progress, true);
+
spin_lock(&unix_gc_lock);
if (!unix_graph_maybe_cyclic) {

View File

@ -1,97 +0,0 @@
From 884d1cab4bfadf53f05ca36f35f06d3cc1f916a2 Mon Sep 17 00:00:00 2001
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
Date: Tue, 4 Aug 2026 10:08:07 +0000
Subject: [PATCH] KVM: x86: Check for invalid/obsolete root *after* making MMU
pages available
JIRA: https://redhat.atlassian.net/browse/RHEL-224013
CVE: CVE-2026-64561
Backported from tree(s): linux
KVM: x86: Check for invalid/obsolete root *after* making MMU pages available
Check for a "stale" page fault, i.e. for an invalid and/or obsolete root,
after making MMU pages available for the shadow MMU. If reclaiming shadow
pages zaps an in-use root, i.e. marks it invalid, then KVM will attempt to
map memory into an invalid root. On its own, populating an invalid root is
"fine", but because child shadow pages inherit their parent's role, any
children created during the map/fetch will be created as invalid pages,
thus violating KVM's invariant that invalid pages are never on the list of
active MMU pages.
Note, the underlying flaw has existed since KVM first started tracking
invalid roots in 2008 (commit 2e53d63acba7, "KVM: MMU: ignore zapped root
pagetables"), but the true badness only came along in 2020 (Linux 5.9)
with the invariant that invalid shadow pages can't be on the list of
active pages.
Note #2, inheriting role.invalid when creating child shadow pages is also
far from ideal; that flaw will be addressed separately.
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
Fixes: f95eec9bed76 ("KVM: x86/mmu: Don't put invalid SPs back on the list of active pages")
Cc: stable@vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 2abd5287f08319fa35764566b15c6e22cb1068db)
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
---
arch/x86/kvm/mmu/mmu.c | 9 +++++----
arch/x86/kvm/mmu/paging_tmpl.h | 10 ++++++----
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index ab4bbb692064..0c4553e57731 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -4814,16 +4814,17 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
if (r != RET_PF_CONTINUE)
return r;
- r = RET_PF_RETRY;
write_lock(&vcpu->kvm->mmu_lock);
- if (is_page_fault_stale(vcpu, fault))
- goto out_unlock;
-
r = make_mmu_pages_available(vcpu);
if (r)
goto out_unlock;
+ if (is_page_fault_stale(vcpu, fault)) {
+ r = RET_PF_RETRY;
+ goto out_unlock;
+ }
+
r = direct_map(vcpu, fault);
out_unlock:
diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h
index 901cd2bd40b8..6465de820e70 100644
--- a/arch/x86/kvm/mmu/paging_tmpl.h
+++ b/arch/x86/kvm/mmu/paging_tmpl.h
@@ -827,15 +827,17 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
}
#endif
- r = RET_PF_RETRY;
write_lock(&vcpu->kvm->mmu_lock);
- if (is_page_fault_stale(vcpu, fault))
- goto out_unlock;
-
r = make_mmu_pages_available(vcpu);
if (r)
goto out_unlock;
+
+ if (is_page_fault_stale(vcpu, fault)) {
+ r = RET_PF_RETRY;
+ goto out_unlock;
+ }
+
r = FNAME(fetch)(vcpu, fault, &walker);
out_unlock:
--
GitLab