On 7/13/26 16:01, Pavel Tikhomirov wrote:


On 7/12/26 21:02, Eva Kurchatova wrote:
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.

There seemingly can be a race between "new" (patched) version of
eventpoll_release_file() and "old" (note yet patched) ep_clear_and_put()
running in concurrent thread. The former skips setting up the dying flag,
and the latter runs concurrently, checks the flags, sees no problem and
does double free. In other direction (former "old" and latter "new")
there is likely the same problem where new ignores what "old" set.

(maybe in one direction locking is ok, but definitely not in both)

So it may not really work like that in RK.

jfyi: live patch documentation says:

Patches are applied on a per-task basis, when the task is deemed safe to
switch over.

Is this an RK series?



Signed-off-by: Eva Kurchatova <[email protected]>

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);


--
Best regards, Riabchun Vladimir
Linux Kernel Developer, Virtuozzo

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to