[Devel] [PATCH vz9 v3 3/3] epoll: Maintain struct compatibility

Eva Kurchatova eva.kurchatova at virtuozzo.com
Sun Jul 12 22:02:05 MSK 2026


This commit maintains structure field runtime compatibility with commit
"epoll: use refcount to reduce ep_mutex contention", which was reverted
to fix CVE-2026-46242 and CVE-2026-43074 that it originally introduced.

The field 'refcount' maintains proper reference counting, which is
ignored as-is and is kept for compatibility purposes. The refcount does
not make the last decrement during ep_free() to prevent underflow WARN,
considering the struct eventpoll is immediately freed afterwards.

The field 'dying' was used for a racing check in eventpoll_release_file
which is meaningless now, but the initialized value of false is safe.

Signed-off-by: Eva Kurchatova <eva.kurchatova at virtuozzo.com>

https://virtuozzo.atlassian.net/browse/VSTOR-137490
Feature: fix epoll cve
---
 fs/eventpoll.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 7e6a5b68c8ba..1b6757935b60 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -153,6 +153,11 @@ struct epitem {
 	/* The file descriptor information this item refers to */
 	struct epoll_filefd ffd;
 
+	/*
+	 * Maintain dying field for livepatch/rollback compatibility
+	 */
+	bool dying;
+
 	/* List containing poll wait queues */
 	struct eppoll_entry *pwqlist;
 
@@ -218,6 +223,11 @@ struct eventpoll {
 	struct hlist_head refs;
 	u8 loop_check_depth;
 
+	/*
+	 * Maintain refcount field for livepatch/rollback compatibility
+	 */
+	refcount_t refcount;
+
 #ifdef CONFIG_NET_RX_BUSY_POLL
 	/* used to track busy poll napi_id */
 	unsigned int napi_id;
@@ -735,6 +745,8 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
 
 	percpu_counter_dec(&ep->user->epoll_watches);
 
+	refcount_dec(&ep->refcount);
+
 	return 0;
 }
 
@@ -993,6 +1005,8 @@ static int ep_alloc(struct eventpoll **pep)
 	ep->ovflist = EP_UNACTIVE_PTR;
 	ep->user = user;
 
+	refcount_set(&ep->refcount, 1);
+
 	*pep = ep;
 
 	return 0;
@@ -1533,6 +1547,8 @@ static int ep_insert(struct eventpoll *ep, const struct epoll_event *event,
 	if (tep)
 		mutex_unlock(&tep->mtx);
 
+	refcount_inc(&ep->refcount);
+
 	/* now check if we've created too many backpaths */
 	if (unlikely(full_check && reverse_path_check())) {
 		ep_remove(ep, epi);
-- 
2.55.0



More information about the Devel mailing list