diff options
| author | Hauke Mehrtens | 2026-04-16 20:24:13 +0000 |
|---|---|---|
| committer | Hauke Mehrtens | 2026-05-23 00:47:56 +0000 |
| commit | f29767f90af112040cdf8a1ee402e5d3d48115b3 (patch) | |
| tree | 850fa0efe5fa332290ba4d2bfb593ae463b121ec | |
| parent | 5849870f2251e7ca67804510446a4d6ca9e9dba2 (diff) | |
| download | ubus-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.c | 7 |
1 files changed, 5 insertions, 2 deletions
@@ -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) |