diff options
| author | Nicholas Carlini <nicholas@carlini.com> | 2026-03-31 15:25:32 +0200 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-04-02 21:45:02 +0200 |
| commit | 07712db80857d5d09ae08f3df85a708ecfc3b61f (patch) | |
| tree | cab0b83e2c0ad5193da1fc9faf41a33591134774 | |
| parent | 1635c2acdde86c4f555b627aec873c8677c421ed (diff) | |
eventpoll: defer struct eventpoll free to RCU grace period
In certain situations, ep_free() in eventpoll.c will kfree the epi->ep
eventpoll struct while it still being used by another concurrent thread.
Defer the kfree() to an RCU callback to prevent UAF.
Fixes: f2e467a48287 ("eventpoll: Fix semi-unbounded recursion")
Signed-off-by: Nicholas Carlini <nicholas@carlini.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
| -rw-r--r-- | fs/eventpoll.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 5714e900567c..4b43bf41296d 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -226,6 +226,9 @@ struct eventpoll { */ refcount_t refcount; + /* used to defer freeing past ep_get_upwards_depth_proc() RCU walk */ + struct rcu_head rcu; + #ifdef CONFIG_NET_RX_BUSY_POLL /* used to track busy poll napi_id */ unsigned int napi_id; @@ -819,7 +822,8 @@ static void ep_free(struct eventpoll *ep) mutex_destroy(&ep->mtx); free_uid(ep->user); wakeup_source_unregister(ep->ws); - kfree(ep); + /* ep_get_upwards_depth_proc() may still hold epi->ep under RCU */ + kfree_rcu(ep, rcu); } /* |
