summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHauke Mehrtens2026-04-16 20:24:13 +0000
committerHauke Mehrtens2026-05-23 00:47:56 +0000
commitf29767f90af112040cdf8a1ee402e5d3d48115b3 (patch)
tree850fa0efe5fa332290ba4d2bfb593ae463b121ec
parent5849870f2251e7ca67804510446a4d6ca9e9dba2 (diff)
downloadubus-f29767f90af112040cdf8a1ee402e5d3d48115b3.tar.gz
libubus: fix file descriptor leaks in ubus_process_msg
ubus_process_msg() receives a file descriptor along with each message but leaked it on several paths: - UBUS_MSG_NOTIFY / UBUS_MSG_UNSUBSCRIBE on a channel context. - UBUS_MSG_INVOKE queued via ubus_queue_msg() when stack_depth > 0 (ubus_queue_msg() does not propagate the fd). - UBUS_MSG_MONITOR in all paths; neither the channel-context check nor the monitor_cb invocation take ownership of the fd. - Any message type not matched by the switch. Close the fd at the end of the function for all paths that do not hand it off to a lower-level handler. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Link: https://github.com/openwrt/ubus/pull/20 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-rw-r--r--libubus.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/libubus.c b/libubus.c
index 5526a9d..555930d 100644
--- a/libubus.c
+++ b/libubus.c
@@ -103,7 +103,7 @@ ubus_process_msg(struct ubus_context *ctx, struct ubus_msghdr_buf *buf, int fd)
case UBUS_MSG_STATUS:
case UBUS_MSG_DATA:
ubus_process_req_msg(ctx, buf, fd);
- break;
+ return;
case UBUS_MSG_UNSUBSCRIBE:
case UBUS_MSG_NOTIFY:
@@ -119,7 +119,7 @@ ubus_process_msg(struct ubus_context *ctx, struct ubus_msghdr_buf *buf, int fd)
ctx->stack_depth++;
ubus_process_obj_msg(ctx, buf, fd);
ctx->stack_depth--;
- break;
+ return;
case UBUS_MSG_MONITOR:
if (ubus_context_is_channel(ctx))
break;
@@ -128,6 +128,9 @@ ubus_process_msg(struct ubus_context *ctx, struct ubus_msghdr_buf *buf, int fd)
ctx->monitor_cb(ctx, buf->hdr.seq, buf->data);
break;
}
+
+ if (fd >= 0)
+ close(fd);
}
static void ubus_process_pending_msg(struct uloop_timeout *timeout)