Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
bab48c5
tg3: Fix race for querying speed/duplex
PlaidCat Jul 10, 2026
ca881b2
netfilter: bridge: make ebt_snat ARP rewrite writable
PlaidCat Jul 10, 2026
958d52c
epoll: annotate racy check
PlaidCat Jul 10, 2026
b6a9316
eventpoll: defer struct eventpoll free to RCU grace period
PlaidCat Jul 10, 2026
cb7a1a5
eventpoll: use hlist_is_singular_node() in __ep_remove()
PlaidCat Jul 10, 2026
3197992
eventpoll: split __ep_remove()
PlaidCat Jul 10, 2026
a1741c0
eventpoll: kill __ep_remove()
PlaidCat Jul 10, 2026
280229b
eventpoll: rename ep_remove_safe() back to ep_remove()
PlaidCat Jul 10, 2026
e475adf
eventpoll: move epi_fget() up
PlaidCat Jul 10, 2026
af6f955
eventpoll: drop vestigial __ prefix from ep_remove_{file,epi}()
PlaidCat Jul 10, 2026
e2993ad
eventpoll: fix ep_remove struct eventpoll / struct file UAF
PlaidCat Jul 10, 2026
5c250a1
eventpoll: move f_lock acquisition into ep_remove_file()
PlaidCat Jul 10, 2026
21026b2
eventpoll: refresh eventpoll_release() fast-path comment
PlaidCat Jul 10, 2026
50a140b
eventpoll: drop dead bool return from ep_remove_epi()
PlaidCat Jul 10, 2026
177c3ec
eventpoll: drop vestigial epi->dying flag
PlaidCat Jul 10, 2026
5ed66b9
eventpoll: Fix integer overflow in ep_loop_check_proc()
PlaidCat Jul 10, 2026
a3a71eb
eventpoll: refresh epi_fget() / ep_remove_file() comments
PlaidCat Jul 10, 2026
5eb87de
net/sched: ets: Always remove class from active list before deleting …
PlaidCat Jul 10, 2026
ba566e3
KVM: x86: Fix shadow paging use-after-free due to unexpected GFN
PlaidCat Jul 10, 2026
da15845
KVM: x86: Fix shadow paging use-after-free due to unexpected role
PlaidCat Jul 10, 2026
699395e
Rebuild rocky9_8 with kernel-5.14.0-687.24.1.el9_8
PlaidCat Jul 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
2 changes: 1 addition & 1 deletion Makefile.rhelver
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ RHEL_MINOR = 8
#
# Use this spot to avoid future merge conflicts.
# Do not trim this comment.
RHEL_RELEASE = 687.22.1
RHEL_RELEASE = 687.24.1

#
# ZSTREAM
Expand Down
41 changes: 18 additions & 23 deletions arch/x86/kvm/mmu/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ struct kmem_cache *mmu_page_header_cache;
static struct percpu_counter kvm_total_used_mmu_pages;

static void mmu_spte_set(u64 *sptep, u64 spte);
static int mmu_page_zap_pte(struct kvm *kvm, struct kvm_mmu_page *sp,
u64 *spte, struct list_head *invalid_list);

struct kvm_mmu_role_regs {
const unsigned long cr0;
Expand Down Expand Up @@ -1220,19 +1222,6 @@ static void drop_spte(struct kvm *kvm, u64 *sptep)
rmap_remove(kvm, sptep);
}

static void drop_large_spte(struct kvm *kvm, u64 *sptep, bool flush)
{
struct kvm_mmu_page *sp;

sp = sptep_to_sp(sptep);
WARN_ON_ONCE(sp->role.level == PG_LEVEL_4K);

drop_spte(kvm, sptep);

if (flush)
kvm_flush_remote_tlbs_sptep(kvm, sptep);
}

/*
* Write-protect on the specified @sptep, @pt_protect indicates whether
* spte write-protection is caused by protecting shadow page table.
Expand Down Expand Up @@ -2326,12 +2315,15 @@ static struct kvm_mmu_page *kvm_mmu_get_child_sp(struct kvm_vcpu *vcpu,
u64 *sptep, gfn_t gfn,
bool direct, unsigned int access)
{
union kvm_mmu_page_role role;
union kvm_mmu_page_role role = kvm_mmu_child_role(sptep, direct, access);

if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep))
if (is_shadow_present_pte(*sptep) &&
!is_large_pte(*sptep) &&
spte_to_child_sp(*sptep) &&
spte_to_child_sp(*sptep)->gfn == gfn &&
spte_to_child_sp(*sptep)->role.word == role.word)
return ERR_PTR(-EEXIST);

role = kvm_mmu_child_role(sptep, direct, access);
return kvm_mmu_get_shadow_page(vcpu, gfn, role);
}

Expand Down Expand Up @@ -2406,13 +2398,16 @@ static void __link_shadow_page(struct kvm *kvm,

BUILD_BUG_ON(VMX_EPT_WRITABLE_MASK != PT_WRITABLE_MASK);

/*
* If an SPTE is present already, it must be a leaf and therefore
* a large one. Drop it, and flush the TLB if needed, before
* installing sp.
*/
if (is_shadow_present_pte(*sptep))
drop_large_spte(kvm, sptep, flush);
if (is_shadow_present_pte(*sptep)) {
struct kvm_mmu_page *parent_sp;
LIST_HEAD(invalid_list);

parent_sp = sptep_to_sp(sptep);
WARN_ON_ONCE(parent_sp->role.level == PG_LEVEL_4K);

mmu_page_zap_pte(kvm, parent_sp, sptep, &invalid_list);
kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, true);
}

spte = make_nonleaf_spte(sp->spt, sp_ad_disabled(sp));

Expand Down
62 changes: 62 additions & 0 deletions ciq/ciq_backports/kernel-5.14.0-687.24.1.el9_8/86e87059.failed
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
eventpoll: move epi_fget() up

jira KERNEL-1279
Rebuild_History Non-Buildable kernel-5.14.0-687.24.1.el9_8
commit-author Christian Brauner <brauner@kernel.org>
commit 86e87059e6d1fd5115a31949726450ed03c1073b
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
Will be included in final tarball splat. Ref for failed cherry-pick at:
ciq/ciq_backports/kernel-5.14.0-687.24.1.el9_8/86e87059.failed

We'll need it when removing files so move it up. No functional change.

Link: https://patch.msgid.link/20260423-work-epoll-uaf-v1-5-2470f9eec0f5@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
(cherry picked from commit 86e87059e6d1fd5115a31949726450ed03c1073b)
Signed-off-by: Jonathan Maple <jmaple@ciq.com>

# Conflicts:
# fs/eventpoll.c
diff --cc fs/eventpoll.c
index f7591c2552f9,5ee4398a6cb8..000000000000
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@@ -887,34 -1047,6 +915,37 @@@ static __poll_t __ep_eventpoll_poll(str
}

/*
++<<<<<<< HEAD
+ * The ffd.file pointer may be in the process of being torn down due to
+ * being closed, but we may not have finished eventpoll_release() yet.
+ *
+ * Normally, even with the atomic_long_inc_not_zero, the file may have
+ * been free'd and then gotten re-allocated to something else (since
+ * files are not RCU-delayed, they are SLAB_TYPESAFE_BY_RCU).
+ *
+ * But for epoll, users hold the ep->mtx mutex, and as such any file in
+ * the process of being free'd will block in eventpoll_release_file()
+ * and thus the underlying file allocation will not be free'd, and the
+ * file re-use cannot happen.
+ *
+ * For the same reason we can avoid a rcu_read_lock() around the
+ * operation - 'ffd.file' cannot go away even if the refcount has
+ * reached zero (but we must still not call out to ->poll() functions
+ * etc).
+ */
+static struct file *epi_fget(const struct epitem *epi)
+{
+ struct file *file;
+
+ file = epi->ffd.file;
+ if (!atomic_long_inc_not_zero(&file->f_count))
+ file = NULL;
+ return file;
+}
+
+/*
++=======
++>>>>>>> 86e87059e6d1 (eventpoll: move epi_fget() up)
* Differs from ep_eventpoll_poll() in that internal callers already have
* the ep->mtx so we need to start from depth=1, such that mutex_lock_nested()
* is correctly annotated.
* Unmerged path fs/eventpoll.c
108 changes: 108 additions & 0 deletions ciq/ciq_backports/kernel-5.14.0-687.24.1.el9_8/a573cb40.failed
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
eventpoll: refresh epi_fget() / ep_remove_file() comments

jira KERNEL-1279
Rebuild_History Non-Buildable kernel-5.14.0-687.24.1.el9_8
commit-author Christian Brauner <brauner@kernel.org>
commit a573cb40f9819c3fe81a43eb10170f8fc8eddc5e
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
Will be included in final tarball splat. Ref for failed cherry-pick at:
ciq/ciq_backports/kernel-5.14.0-687.24.1.el9_8/a573cb40.failed

Two comments drifted from the code they sit on.

epi_fget()'s block comment still referenced atomic_long_inc_not_zero,
which has been file_ref_get() for a while, and described only one of
the function's two roles: safe dereference of epi->ffd.file under
ep->mtx. Since commit a6dc643c6931 ("eventpoll: fix ep_remove struct
eventpoll / struct file UAF") the refcount bump also serves as a pin
that blocks __fput() from starting, which is what lets ep_remove()
touch file->f_lock and file->f_ep without racing
eventpoll_release_file(). Update the block to name both roles and the
commit that introduced the pin role.

ep_remove_file()'s one-line "See eventpoll_release() for details"
pointed at an inline in include/linux/eventpoll.h but said nothing
about what those details were. Replace it with a short explanation:
we publish NULL so the eventpoll_release() fastpath can skip the slow
path, and this is safe because every f_ep writer either holds a pin
via epi_fget() or is __fput() itself.

Comment-only; no functional change.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Link: https://patch.msgid.link/20260424-work-epoll-rework-v1-4-249ed00a20f3@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit a573cb40f9819c3fe81a43eb10170f8fc8eddc5e)
Signed-off-by: Jonathan Maple <jmaple@ciq.com>

# Conflicts:
# fs/eventpoll.c
diff --cc fs/eventpoll.c
index d7653c4e4c3d,1039d9737ce9..000000000000
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@@ -706,20 -991,55 +706,59 @@@ static void ep_free(struct eventpoll *e
}

/*
++<<<<<<< HEAD
+ * Called with &file->f_lock held,
+ * returns with it released
++=======
+ * Pin @epi->ffd.file for operations that require both safe dereference
+ * and exclusion from __fput().
+ *
+ * struct file uses SLAB_TYPESAFE_BY_RCU, so a freed slot can be
+ * reassigned at any time. The bare load of epi->ffd.file is safe here
+ * because the caller holds ep->mtx and eventpoll_release_file() blocks
+ * on that mutex while tearing down the epi, so the backing file
+ * allocation cannot be freed and reused under us. An rcu_read_lock()
+ * is therefore unnecessary for the load.
+ *
+ * A successful file_ref_get() additionally blocks __fput() from
+ * starting on this file: once the refcount has reached zero it cannot
+ * come back. ep_remove() relies on that to touch file->f_lock and
+ * file->f_ep without racing eventpoll_release_file() (see commit
+ * a6dc643c6931). A NULL return means __fput() is already in flight;
+ * the caller must bail without touching the file, and
+ * eventpoll_release_file() will clean the epi up from its side.
+ */
+ static struct file *epi_fget(const struct epitem *epi)
+ {
+ struct file *file;
+
+ file = epi->ffd.file;
+ if (!file_ref_get(&file->f_ref))
+ file = NULL;
+ return file;
+ }
+
+ /*
+ * Takes &file->f_lock; returns with it released.
++>>>>>>> a573cb40f981 (eventpoll: refresh epi_fget() / ep_remove_file() comments)
*/
static void ep_remove_file(struct eventpoll *ep, struct epitem *epi,
struct file *file)
{
struct epitems_head *to_free = NULL;
- struct hlist_head *head;
+ struct hlist_head *head = file->f_ep;

lockdep_assert_held(&ep->mtx);
+ lockdep_assert_held(&file->f_lock);

- spin_lock(&file->f_lock);
- head = file->f_ep;
if (hlist_is_singular_node(&epi->fllink, head)) {
- /* See eventpoll_release() for details. */
+ /*
+ * Last watcher: publish NULL so the eventpoll_release()
+ * fastpath in include/linux/eventpoll.h can skip the slow
+ * path on a future __fput(). Safe because every f_ep writer
+ * either holds a pin on @file via epi_fget() or is __fput()
+ * itself -- see the comment in eventpoll_release().
+ */
WRITE_ONCE(file->f_ep, NULL);
if (!is_file_epoll(file)) {
struct epitems_head *v;
* Unmerged path fs/eventpoll.c
68 changes: 68 additions & 0 deletions ciq/ciq_backports/kernel-5.14.0-687.24.1.el9_8/d30deeb8.failed
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
eventpoll: move f_lock acquisition into ep_remove_file()

jira KERNEL-1279
Rebuild_History Non-Buildable kernel-5.14.0-687.24.1.el9_8
commit-author Christian Brauner <brauner@kernel.org>
commit d30deeb8b0cf6259785c1fb79b87905d281b0a5a
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
Will be included in final tarball splat. Ref for failed cherry-pick at:
ciq/ciq_backports/kernel-5.14.0-687.24.1.el9_8/d30deeb8.failed

Let the helper own its critical section end-to-end: take &file->f_lock
at the top, read file->f_ep inside the lock, release on exit. Callers
(ep_remove() and eventpoll_release_file()) no longer need to wrap the
call, and the function-comment lock-handoff contract is gone.

Link: https://patch.msgid.link/20260423-work-epoll-uaf-v1-7-2470f9eec0f5@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
(cherry picked from commit d30deeb8b0cf6259785c1fb79b87905d281b0a5a)
Signed-off-by: Jonathan Maple <jmaple@ciq.com>

# Conflicts:
# fs/eventpoll.c
diff --cc fs/eventpoll.c
index b5458e7b06e1,3f99ff54626f..000000000000
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@@ -716,8 -827,35 +716,40 @@@ static void ep_free(struct eventpoll *e
}

/*
++<<<<<<< HEAD
+ * Called with &file->f_lock held,
+ * returns with it released
++=======
+ * The ffd.file pointer may be in the process of being torn down due to
+ * being closed, but we may not have finished eventpoll_release() yet.
+ *
+ * Normally, even with the atomic_long_inc_not_zero, the file may have
+ * been free'd and then gotten re-allocated to something else (since
+ * files are not RCU-delayed, they are SLAB_TYPESAFE_BY_RCU).
+ *
+ * But for epoll, users hold the ep->mtx mutex, and as such any file in
+ * the process of being free'd will block in eventpoll_release_file()
+ * and thus the underlying file allocation will not be free'd, and the
+ * file re-use cannot happen.
+ *
+ * For the same reason we can avoid a rcu_read_lock() around the
+ * operation - 'ffd.file' cannot go away even if the refcount has
+ * reached zero (but we must still not call out to ->poll() functions
+ * etc).
+ */
+ static struct file *epi_fget(const struct epitem *epi)
+ {
+ struct file *file;
+
+ file = epi->ffd.file;
+ if (!file_ref_get(&file->f_ref))
+ file = NULL;
+ return file;
+ }
+
+ /*
+ * Takes &file->f_lock; returns with it released.
++>>>>>>> d30deeb8b0cf (eventpoll: move f_lock acquisition into ep_remove_file())
*/
static void ep_remove_file(struct eventpoll *ep, struct epitem *epi,
struct file *file)
* Unmerged path fs/eventpoll.c
22 changes: 22 additions & 0 deletions ciq/ciq_backports/kernel-5.14.0-687.24.1.el9_8/rebuild.details.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Rebuild_History BUILDABLE
Rebuilding Kernel from rpm changelog with Fuzz Limit: 87.50%
Number of commits in upstream range v5.14~1..kernel-mainline: 394115
Number of commits in rpm: 23
Number of commits matched with upstream: 20 (86.96%)
Number of commits in upstream but not in rpm: 394095
Number of commits NOT found in upstream: 3 (13.04%)

Rebuilding Kernel on Branch rocky9_8_rebuild_kernel-5.14.0-687.24.1.el9_8 for kernel-5.14.0-687.24.1.el9_8
Clean Cherry Picks: 17 (85.00%)
Empty Cherry Picks: 3 (15.00%)
_______________________________

__EMPTY COMMITS__________________________
86e87059e6d1fd5115a31949726450ed03c1073b eventpoll: move epi_fget() up
d30deeb8b0cf6259785c1fb79b87905d281b0a5a eventpoll: move f_lock acquisition into ep_remove_file()
a573cb40f9819c3fe81a43eb10170f8fc8eddc5e eventpoll: refresh epi_fget() / ep_remove_file() comments

__CHANGES NOT IN UPSTREAM________________
Replace sbat with Rocky Linux sbat
Change bug tracker URL
Ensure appended release in sbat is removed'
Loading
Loading