+7
−20
Loading
With ep_remove() now pinning @file via epi_fget() across the f_ep clear and hlist_del_rcu(), the dying flag no longer orchestrates anything: it was set in eventpoll_release_file() (which only runs from __fput(), i.e. after @file's refcount has reached zero) and read in __ep_remove() / ep_remove() as a cheap bail before attempting the same synchronization epi_fget() now provides unconditionally. The implication is simple: epi->dying == true always coincides with file_ref_get(&file->f_ref) == false, because __fput() is reachable only once the refcount hits zero and the refcount is monotone in that state. The READ_ONCE(epi->dying) in ep_remove() therefore selects exactly the same callers that epi_fget() would reject, just one atomic cheaper. That's not worth a struct field, a second coordination mechanism, and the comments on both. Refresh the eventpoll_release_file() comment to describe what actually makes the path race-free now (the pin in ep_remove()). No functional change: the correctness argument is unchanged, only the mechanism is now a single one instead of two. Link: https://patch.msgid.link/20260423-work-epoll-uaf-v1-10-2470f9eec0f5@kernel.org Signed-off-by:Christian Brauner (Amutable) <brauner@kernel.org>