ubus: unregister ubus subscriber on HTTP client disconnect master
authorTito Brasolin <tito.brasolin@kerberos.energy>
Fri, 5 Sep 2025 08:09:16 +0000 (10:09 +0200)
committerRobert Marko <robert.marko@sartura.hr>
Wed, 24 Dec 2025 10:08:44 +0000 (11:08 +0100)
Fixes a potential SIGSEGV when a client disconnects from a /ubus/subscribe/... endpoint without unsubscribing.
The ubus subscriber is now properly unregistered in a cleanup handler, preventing callbacks on freed client structures.

Fixes: #1
Signed-off-by: Tito Brasolin <tito.brasolin@kerberos.energy>
Link: https://github.com/openwrt/uhttpd/pull/18
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
ubus.c

diff --git a/ubus.c b/ubus.c
index 99cc400fe3d007e6c2076a6e6f43ecb37d65fb23..4b1546682d929bf889975acd5fc56aaa8cb903d1 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -362,6 +362,14 @@ static void uh_ubus_subscription_notification_remove_cb(struct ubus_context *ctx
        ops->request_done(cl);
 }
 
+/* Cleanup function to unregister ubus subscriber when HTTP client closes */
+static void uh_ubus_subscription_free(struct client *cl)
+{
+       struct dispatch_ubus *du = &cl->dispatch.ubus;
+       if (du->sub.obj.id)
+               ubus_unregister_subscriber(ctx, &du->sub);
+}
+
 static void uh_ubus_handle_get_subscribe(struct client *cl, const char *path)
 {
        struct dispatch_ubus *du = &cl->dispatch.ubus;
@@ -399,6 +407,9 @@ static void uh_ubus_handle_get_subscribe(struct client *cl, const char *path)
        if (conf.events_retry)
                ops->chunk_printf(cl, "retry: %d\n", conf.events_retry);
 
+       /* Ensure cleanup on client disconnect */
+       cl->dispatch.free = uh_ubus_subscription_free;
+
        return;
 
 err_unregister: