This is an automated email from the git hooks/post-receive script.

git pushed a commit to reference refs/pull/132/head
in repository enlightenment.

View the commit online.

commit 3f68e2d824ba50f7c343eaed25bdd716c8157379
Author: [email protected] <[email protected]>
AuthorDate: Sun May 17 16:09:32 2026 -0600

    fix(networkmanager): fix use-after-free in _device_free on wireless proxy teardown
    
    The _device_free() function had a use-after-free bug triggered on every
    Wi-Fi device shutdown: both dev->proxy (NM_IFACE_PROPS) and
    dev->wireless_proxy (NM_IFACE_WIFI) are child proxies of a shared
    Eldbus_Object. The old code called eldbus_object_unref() in the
    wireless-proxy block, prematurely dropping the object's refcount to zero.
    
    eldbus then ran _eldbus_object_clear, which freed all child proxies via
    the object's _on_object_free callback — including dev->proxy. When
    execution reached the dev->proxy block below, it dereferenced freed
    memory, crashing with "Eina Magic Check Failed ... Input handle has
    already been freed".
    
    Fix: remove the erroneous eldbus_proxy_object_get/eldbus_object_unref
    from the wireless block. The shared object's single reference (taken
    once in _device_new) must be released exactly once, in the dev->proxy
    block where it is retrieved and both proxies have finished their
    cleanup. This way eldbus's _on_object_free cascade correctly frees the
    wireless_proxy as a side-effect of dev->proxy teardown.
    
    Verified under valgrind: crash signature and invalid reads gone; no
    regressions on non-Wi-Fi path; full E shutdown clean on both paths.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
---
 src/modules/networkmanager/e_networkmanager.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/modules/networkmanager/e_networkmanager.c b/src/modules/networkmanager/e_networkmanager.c
index 3fee61041..c36736c49 100644
--- a/src/modules/networkmanager/e_networkmanager.c
+++ b/src/modules/networkmanager/e_networkmanager.c
@@ -742,7 +742,6 @@ _device_free(struct NM_Device *dev)
 
    if (dev->wireless_proxy)
      {
-        Eldbus_Object *wobj = eldbus_proxy_object_get(dev->wireless_proxy);
         if (dev->ap_added_handler)
           {
              eldbus_signal_handler_del(dev->ap_added_handler);
@@ -753,8 +752,13 @@ _device_free(struct NM_Device *dev)
              eldbus_signal_handler_del(dev->ap_removed_handler);
              dev->ap_removed_handler = NULL;
           }
+        /* wireless_proxy shares the same Eldbus_Object as dev->proxy.
+         * eldbus_proxy_get() does NOT increment the object's refcount, so
+         * proxy_unref here must NOT be paired with an object_unref — doing so
+         * would drop the object to refcount 0, triggering _eldbus_object_clear
+         * which frees dev->proxy via its _on_object_free callback, causing a
+         * use-after-free when the dev->proxy block below runs. */
         eldbus_proxy_unref(dev->wireless_proxy);
-        if (wobj) eldbus_object_unref(wobj);
      }
 
    if (dev->proxy)
@@ -764,6 +768,9 @@ _device_free(struct NM_Device *dev)
              eldbus_signal_handler_del(dev->prop_changed_handler);
              dev->prop_changed_handler = NULL;
           }
+        /* The sole object ref belongs to this proxy (taken by eldbus_object_get
+         * in _device_new and never stored separately). Unref proxy first, then
+         * unref the object exactly once. */
         obj = eldbus_proxy_object_get(dev->proxy);
         eldbus_proxy_unref(dev->proxy);
         eldbus_object_unref(obj);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to