Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

+23 -4
+23 -4
fs/eventpoll.c
··· 826 826 kfree_rcu(ep, rcu); 827 827 } 828 828 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 + 829 832 /* 830 833 * Removes a "struct epitem" from the eventpoll RB tree and deallocates 831 834 * all the associated resources. Must be called with "mtx" held. ··· 840 837 static bool __ep_remove(struct eventpoll *ep, struct epitem *epi, bool force) 841 838 { 842 839 struct file *file = epi->ffd.file; 843 - struct epitems_head *to_free; 844 - struct hlist_head *head; 845 840 846 841 lockdep_assert_irqs_enabled(); 847 842 ··· 855 854 return false; 856 855 } 857 856 858 - to_free = NULL; 859 - head = file->f_ep; 857 + __ep_remove_file(ep, epi, file); 858 + return __ep_remove_epi(ep, epi); 859 + } 860 + 861 + /* 862 + * Called with &file->f_lock held, 863 + * returns with it released 864 + */ 865 + static void __ep_remove_file(struct eventpoll *ep, struct epitem *epi, struct file *file) 866 + { 867 + struct epitems_head *to_free = NULL; 868 + struct hlist_head *head = file->f_ep; 869 + 870 + lockdep_assert_held(&ep->mtx); 871 + 860 872 if (hlist_is_singular_node(&epi->fllink, head)) { 861 873 /* See eventpoll_release() for details. */ 862 874 WRITE_ONCE(file->f_ep, NULL); ··· 883 869 hlist_del_rcu(&epi->fllink); 884 870 spin_unlock(&file->f_lock); 885 871 free_ephead(to_free); 872 + } 873 + 874 + static bool __ep_remove_epi(struct eventpoll *ep, struct epitem *epi) 875 + { 876 + lockdep_assert_held(&ep->mtx); 886 877 887 878 rb_erase_cached(&epi->rbn, &ep->rbr); 888 879