Recreate RHEL 5.14.0-687.24.1 from upstream backports

- Drop AlmaLinux ahead-of-RHEL KVM x86 shadow paging fixes (1710, 1711),
  superseded by RHEL's copies in 687.24.1
- Add RHEL 687.24.1 backports recreated from upstream stable (1758-1760)
- Keep the rtmutex remove_waiter() fixes (1756, 1757)
This commit is contained in:
Andrew Lukoshko 2026-07-09 20:43:55 +00:00
parent 8d60f43faa
commit ae889222a0
4 changed files with 248 additions and 20 deletions

View File

@ -0,0 +1,227 @@
From c7f6e7cc14df72b997258216e99d897d2df0dbbd Mon Sep 17 00:00:00 2001
From: Jamal Hadi Salim <jhs@mojatatu.com>
Date: Fri, 28 Nov 2025 10:19:19 -0500
Subject: [PATCH] net/sched: ets: Always remove class from active list before
deleting in ets_qdisc_change
[ Upstream commit ce052b9402e461a9aded599f5b47e76bc727f7de ]
zdi-disclosures@trendmicro.com says:
The vulnerability is a race condition between `ets_qdisc_dequeue` and
`ets_qdisc_change`. It leads to UAF on `struct Qdisc` object.
Attacker requires the capability to create new user and network namespace
in order to trigger the bug.
See my additional commentary at the end of the analysis.
Analysis:
static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
...
// (1) this lock is preventing .change handler (`ets_qdisc_change`)
//to race with .dequeue handler (`ets_qdisc_dequeue`)
sch_tree_lock(sch);
for (i = nbands; i < oldbands; i++) {
if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
list_del_init(&q->classes[i].alist);
qdisc_purge_queue(q->classes[i].qdisc);
}
WRITE_ONCE(q->nbands, nbands);
for (i = nstrict; i < q->nstrict; i++) {
if (q->classes[i].qdisc->q.qlen) {
// (2) the class is added to the q->active
list_add_tail(&q->classes[i].alist, &q->active);
q->classes[i].deficit = quanta[i];
}
}
WRITE_ONCE(q->nstrict, nstrict);
memcpy(q->prio2band, priomap, sizeof(priomap));
for (i = 0; i < q->nbands; i++)
WRITE_ONCE(q->classes[i].quantum, quanta[i]);
for (i = oldbands; i < q->nbands; i++) {
q->classes[i].qdisc = queues[i];
if (q->classes[i].qdisc != &noop_qdisc)
qdisc_hash_add(q->classes[i].qdisc, true);
}
// (3) the qdisc is unlocked, now dequeue can be called in parallel
// to the rest of .change handler
sch_tree_unlock(sch);
ets_offload_change(sch);
for (i = q->nbands; i < oldbands; i++) {
// (4) we're reducing the refcount for our class's qdisc and
// freeing it
qdisc_put(q->classes[i].qdisc);
// (5) If we call .dequeue between (4) and (5), we will have
// a strong UAF and we can control RIP
q->classes[i].qdisc = NULL;
WRITE_ONCE(q->classes[i].quantum, 0);
q->classes[i].deficit = 0;
gnet_stats_basic_sync_init(&q->classes[i].bstats);
memset(&q->classes[i].qstats, 0, sizeof(q->classes[i].qstats));
}
return 0;
}
Comment:
This happens because some of the classes have their qdiscs assigned to
NULL, but remain in the active list. This commit fixes this issue by always
removing the class from the active list before deleting and freeing its
associated qdisc
Reproducer Steps
(trimmed version of what was sent by zdi-disclosures@trendmicro.com)
```
DEV="${DEV:-lo}"
ROOT_HANDLE="${ROOT_HANDLE:-1:}"
BAND2_HANDLE="${BAND2_HANDLE:-20:}" # child under 1:2
PING_BYTES="${PING_BYTES:-48}"
PING_COUNT="${PING_COUNT:-200000}"
PING_DST="${PING_DST:-127.0.0.1}"
SLOW_TBF_RATE="${SLOW_TBF_RATE:-8bit}"
SLOW_TBF_BURST="${SLOW_TBF_BURST:-100b}"
SLOW_TBF_LAT="${SLOW_TBF_LAT:-1s}"
cleanup() {
tc qdisc del dev "$DEV" root 2>/dev/null
}
trap cleanup EXIT
ip link set "$DEV" up
tc qdisc del dev "$DEV" root 2>/dev/null || true
tc qdisc add dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
tc qdisc add dev "$DEV" parent 1:2 handle "$BAND2_HANDLE" \
tbf rate "$SLOW_TBF_RATE" burst "$SLOW_TBF_BURST" latency "$SLOW_TBF_LAT"
tc filter add dev "$DEV" parent 1: protocol all prio 1 u32 match u32 0 0 flowid 1:2
tc -s qdisc ls dev $DEV
ping -I "$DEV" -f -c "$PING_COUNT" -s "$PING_BYTES" -W 0.001 "$PING_DST" \
>/dev/null 2>&1 &
tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 0
tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
tc -s qdisc ls dev $DEV
tc qdisc del dev "$DEV" parent 1:2 || true
tc -s qdisc ls dev $DEV
tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 1 strict 1
```
KASAN report
```
==================================================================
BUG: KASAN: slab-use-after-free in ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
Read of size 8 at addr ffff8880502fc018 by task ping/12308
>
CPU: 0 UID: 0 PID: 12308 Comm: ping Not tainted 6.18.0-rc4-dirty #1 PREEMPT(full)
Hardware name: QEMU Ubuntu 25.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<IRQ>
__dump_stack kernel/lib/dump_stack.c:94
dump_stack_lvl+0x100/0x190 kernel/lib/dump_stack.c:120
print_address_description kernel/mm/kasan/report.c:378
print_report+0x156/0x4c9 kernel/mm/kasan/report.c:482
kasan_report+0xdf/0x110 kernel/mm/kasan/report.c:595
ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
dequeue_skb kernel/net/sched/sch_generic.c:294
qdisc_restart kernel/net/sched/sch_generic.c:399
__qdisc_run+0x1c9/0x1b00 kernel/net/sched/sch_generic.c:417
__dev_xmit_skb kernel/net/core/dev.c:4221
__dev_queue_xmit+0x2848/0x4410 kernel/net/core/dev.c:4729
dev_queue_xmit kernel/./include/linux/netdevice.h:3365
[...]
Allocated by task 17115:
kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
poison_kmalloc_redzone kernel/mm/kasan/common.c:400
__kasan_kmalloc+0xaa/0xb0 kernel/mm/kasan/common.c:417
kasan_kmalloc kernel/./include/linux/kasan.h:262
__do_kmalloc_node kernel/mm/slub.c:5642
__kmalloc_node_noprof+0x34e/0x990 kernel/mm/slub.c:5648
kmalloc_node_noprof kernel/./include/linux/slab.h:987
qdisc_alloc+0xb8/0xc30 kernel/net/sched/sch_generic.c:950
qdisc_create_dflt+0x93/0x490 kernel/net/sched/sch_generic.c:1012
ets_class_graft+0x4fd/0x800 kernel/net/sched/sch_ets.c:261
qdisc_graft+0x3e4/0x1780 kernel/net/sched/sch_api.c:1196
[...]
Freed by task 9905:
kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
__kasan_save_free_info+0x3b/0x70 kernel/mm/kasan/generic.c:587
kasan_save_free_info kernel/mm/kasan/kasan.h:406
poison_slab_object kernel/mm/kasan/common.c:252
__kasan_slab_free+0x5f/0x80 kernel/mm/kasan/common.c:284
kasan_slab_free kernel/./include/linux/kasan.h:234
slab_free_hook kernel/mm/slub.c:2539
slab_free kernel/mm/slub.c:6630
kfree+0x144/0x700 kernel/mm/slub.c:6837
rcu_do_batch kernel/kernel/rcu/tree.c:2605
rcu_core+0x7c0/0x1500 kernel/kernel/rcu/tree.c:2861
handle_softirqs+0x1ea/0x8a0 kernel/kernel/softirq.c:622
__do_softirq kernel/kernel/softirq.c:656
[...]
Commentary:
1. Maher Azzouzi working with Trend Micro Zero Day Initiative was reported as
the person who found the issue. I requested to get a proper email to add to the
reported-by tag but got no response. For this reason i will credit the person
i exchanged emails with i.e zdi-disclosures@trendmicro.com
2. Neither i nor Victor who did a much more thorough testing was able to
reproduce a UAF with the PoC or other approaches we tried. We were both able to
reproduce a null ptr deref. After exchange with zdi-disclosures@trendmicro.com
they sent a small change to be made to the code to add an extra delay which
was able to simulate the UAF. i.e, this:
qdisc_put(q->classes[i].qdisc);
mdelay(90);
q->classes[i].qdisc = NULL;
I was informed by Thomas Gleixner(tglx@linutronix.de) that adding delays was
acceptable approach for demonstrating the bug, quote:
"Adding such delays is common exploit validation practice"
The equivalent delay could happen "by virt scheduling the vCPU out, SMIs,
NMIs, PREEMPT_RT enabled kernel"
3. I asked the OP to test and report back but got no response and after a
few days gave up and proceeded to submit this fix.
Fixes: de6d25924c2a ("net/sched: sch_ets: don't peek at classes beyond 'nbands'")
Reported-by: zdi-disclosures@trendmicro.com
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Davide Caratti <dcaratti@redhat.com>
Link: https://patch.msgid.link/20251128151919.576920-1-jhs@mojatatu.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
index d95d12797525..bcd91ffe9bc6 100644
--- a/net/sched/sch_ets.c
+++ b/net/sched/sch_ets.c
@@ -665,7 +665,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
sch_tree_lock(sch);
for (i = nbands; i < oldbands; i++) {
- if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
+ if (cl_is_active(&q->classes[i]))
list_del_init(&q->classes[i].alist);
qdisc_purge_queue(q->classes[i].qdisc);
}
--
2.50.1 (Apple Git-155)

View File

@ -58,12 +58,9 @@ Cc: stable@vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
Link: https://patch.msgid.link/20260503201029.106481-1-pbonzini@redhat.com/
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/kvm/mmu/mmu.c | 35 ++++++++++++++---------------------
1 file changed, 14 insertions(+), 21 deletions(-)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 8895c98..6140702 100644
index 8895c98f0..6140702e1 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -183,6 +183,8 @@ struct kmem_cache *mmu_page_header_cache;
@ -129,6 +126,3 @@ index 8895c98..6140702 100644
spte = make_nonleaf_spte(sp->spt, sp_ad_disabled(sp));
--
2.43.0

View File

@ -34,12 +34,9 @@ use-after-free.
Fixes: 2032a93d66fa ("KVM: MMU: Don't allocate gfns page for direct mmu pages")
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/kvm/mmu/mmu.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 6140702..8996c89 100644
index 6140702e1..8996c8965 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -2315,13 +2315,15 @@ static struct kvm_mmu_page *kvm_mmu_get_child_sp(struct kvm_vcpu *vcpu,
@ -62,6 +59,3 @@ index 6140702..8996c89 100644
return kvm_mmu_get_shadow_page(vcpu, gfn, role);
}
--
2.43.0

View File

@ -176,13 +176,13 @@ Summary: The Linux kernel
# define buildid .local
%define specversion 5.14.0
%define patchversion 5.14
%define pkgrelease 687.23.2
%define pkgrelease 687.24.1
%define kversion 5
%define tarfile_release 5.14.0-687.5.1.el9_8
# This is needed to do merge window version magic
%define patchlevel 14
# This allows pkg_release to have configurable %%{?dist} tag
%define specrelease 687.23.2%{?buildid}%{?dist}
%define specrelease 687.24.1%{?buildid}%{?dist}
# This defines the kabi tarball version
%define kabiversion 5.14.0-687.5.1.el9_8
@ -1587,8 +1587,6 @@ Patch1706: 1706-crypto-testmgr-allow-authenc-hmac-sha-256-384-cts-cbc-aes-in.pat
Patch1707: 1707-crypto-krb5enc-fix-sleepable-flag-handling-in-encrypt-dispat.patch
Patch1708: 1708-crypto-krb5enc-fix-async-decrypt-skipping-hash-verification.patch
Patch1709: 1709-crypto-krb5-filter-out-async-aead-implementations-at-alloc.patch
Patch1710: 1710-kvm-x86-fix-shadow-paging-use-after-free-due-to-unexpected-gfn.patch
Patch1711: 1711-kvm-x86-fix-shadow-paging-use-after-free-due-to-unexpected-role.patch
Patch1713: 1713-nouveau-gsp-drop-warn-on-in-acpi-probes.patch
Patch1714: 1714-sctp-revalidate-list-cursor-after-sctp-sendmsg-to-asoc-in-sc.patch
Patch1715: 1715-drm-gem-fix-inconsistent-plane-dimension-calculation-in-drm.patch
@ -1630,6 +1628,9 @@ Patch1754: 1754-eventpoll-fix-integer-overflow-in-ep-loop-check-proc.patch
Patch1755: 1755-eventpoll-refresh-epi-fget-ep-remove-file-comments.patch
Patch1756: 1756-rtmutex-use-waiter-task-in-remove-waiter.patch
Patch1757: 1757-rtmutex-skip-remove-waiter-when-not-enqueued.patch
Patch1758: 1758-net-sched-ets-always-remove-class-from-active-list-before-deleting.patch
Patch1759: 1759-kvm-x86-fix-shadow-paging-use-after-free-due-to-unexpected-gfn.patch
Patch1760: 1760-kvm-x86-fix-shadow-paging-use-after-free-due-to-unexpected-role.patch
# END OF PATCH DEFINITIONS
%description
@ -2984,8 +2985,6 @@ ApplyPatch 1706-crypto-testmgr-allow-authenc-hmac-sha-256-384-cts-cbc-aes-in.pat
ApplyPatch 1707-crypto-krb5enc-fix-sleepable-flag-handling-in-encrypt-dispat.patch
ApplyPatch 1708-crypto-krb5enc-fix-async-decrypt-skipping-hash-verification.patch
ApplyPatch 1709-crypto-krb5-filter-out-async-aead-implementations-at-alloc.patch
ApplyPatch 1710-kvm-x86-fix-shadow-paging-use-after-free-due-to-unexpected-gfn.patch
ApplyPatch 1711-kvm-x86-fix-shadow-paging-use-after-free-due-to-unexpected-role.patch
ApplyPatch 1713-nouveau-gsp-drop-warn-on-in-acpi-probes.patch
ApplyPatch 1714-sctp-revalidate-list-cursor-after-sctp-sendmsg-to-asoc-in-sc.patch
ApplyPatch 1715-drm-gem-fix-inconsistent-plane-dimension-calculation-in-drm.patch
@ -3027,6 +3026,9 @@ ApplyPatch 1754-eventpoll-fix-integer-overflow-in-ep-loop-check-proc.patch
ApplyPatch 1755-eventpoll-refresh-epi-fget-ep-remove-file-comments.patch
ApplyPatch 1756-rtmutex-use-waiter-task-in-remove-waiter.patch
ApplyPatch 1757-rtmutex-skip-remove-waiter-when-not-enqueued.patch
ApplyPatch 1758-net-sched-ets-always-remove-class-from-active-list-before-deleting.patch
ApplyPatch 1759-kvm-x86-fix-shadow-paging-use-after-free-due-to-unexpected-gfn.patch
ApplyPatch 1760-kvm-x86-fix-shadow-paging-use-after-free-due-to-unexpected-role.patch
# END OF PATCH APPLICATIONS
# Any further pre-build tree manipulations happen here.
@ -5101,6 +5103,17 @@ fi
#
#
%changelog
* Thu Jul 09 2026 Andrew Lukoshko <alukoshko@almalinux.org> - 5.14.0-687.24.1
- Recreate RHEL 5.14.0-687.24.1 from upstream stable backports (1758-1760)
- The AlmaLinux ahead-of-RHEL KVM x86 shadow paging fixes (1710, 1711) are
superseded by RHEL's copies and dropped
- RHEL changelog for 687.24.1 follows:
* Tue Jul 07 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-687.24.1.el9_8]
- KVM: x86: Fix shadow paging use-after-free due to unexpected role (Paolo Bonzini) [RHEL-192400] {CVE-2026-53359}
- KVM: x86: Fix shadow paging use-after-free due to unexpected GFN (CKI Backport Bot) [RHEL-186702] {CVE-2026-46113}
- net/sched: ets: Always remove class from active list before deleting in ets_qdisc_change (CKI Backport Bot) [RHEL-183004] {CVE-2025-71066}
* Wed Jul 08 2026 Andrew Lukoshko <alukoshko@almalinux.org> - 5.14.0-687.23.2
- Bring back the rtmutex self-deadlock NULL pointer dereference fixes in
remove_waiter() ahead of RHEL, upstream 3bfdc63936dd + 40a25d59e85b (1756, 1757)