Skip to content

Commit 0f7bdfd

Browse files
committed
eventpoll: split __ep_remove()
Split __ep_remove() to delineate file removal from epoll item removal. Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Link: https://patch.msgid.link/20260423-work-epoll-uaf-v1-2-2470f9eec0f5@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
1 parent 3d9fd0a commit 0f7bdfd

1 file changed

Lines changed: 23 additions & 4 deletions

File tree

fs/eventpoll.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,9 @@ static void ep_free(struct eventpoll *ep)
826826
kfree_rcu(ep, rcu);
827827
}
828828

829+
static void __ep_remove_file(struct eventpoll *ep, struct epitem *epi, struct file *file);
830+
static bool __ep_remove_epi(struct eventpoll *ep, struct epitem *epi);
831+
829832
/*
830833
* Removes a "struct epitem" from the eventpoll RB tree and deallocates
831834
* all the associated resources. Must be called with "mtx" held.
@@ -837,8 +840,6 @@ static void ep_free(struct eventpoll *ep)
837840
static bool __ep_remove(struct eventpoll *ep, struct epitem *epi, bool force)
838841
{
839842
struct file *file = epi->ffd.file;
840-
struct epitems_head *to_free;
841-
struct hlist_head *head;
842843

843844
lockdep_assert_irqs_enabled();
844845

@@ -854,8 +855,21 @@ static bool __ep_remove(struct eventpoll *ep, struct epitem *epi, bool force)
854855
return false;
855856
}
856857

857-
to_free = NULL;
858-
head = file->f_ep;
858+
__ep_remove_file(ep, epi, file);
859+
return __ep_remove_epi(ep, epi);
860+
}
861+
862+
/*
863+
* Called with &file->f_lock held,
864+
* returns with it released
865+
*/
866+
static void __ep_remove_file(struct eventpoll *ep, struct epitem *epi, struct file *file)
867+
{
868+
struct epitems_head *to_free = NULL;
869+
struct hlist_head *head = file->f_ep;
870+
871+
lockdep_assert_held(&ep->mtx);
872+
859873
if (hlist_is_singular_node(&epi->fllink, head)) {
860874
/* See eventpoll_release() for details. */
861875
WRITE_ONCE(file->f_ep, NULL);
@@ -869,6 +883,11 @@ static bool __ep_remove(struct eventpoll *ep, struct epitem *epi, bool force)
869883
hlist_del_rcu(&epi->fllink);
870884
spin_unlock(&file->f_lock);
871885
free_ephead(to_free);
886+
}
887+
888+
static bool __ep_remove_epi(struct eventpoll *ep, struct epitem *epi)
889+
{
890+
lockdep_assert_held(&ep->mtx);
872891

873892
rb_erase_cached(&epi->rbn, &ep->rbr);
874893

0 commit comments

Comments
 (0)