Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4b27405
libubus: fix NULL dereference on OOM in ubus_queue_msg
hauke Apr 12, 2026
8b5be57
libubus-acl: fix dangling pointers on blob_memdup failure in acl_recv_cb
hauke Apr 12, 2026
9105ea2
ubusd_acl: fix NULL dereference on OOM in ubusd_acl_alloc_obj
hauke Apr 12, 2026
07d7f34
ubusd_acl: handle allocation failures in ubusd_acl_init_client
hauke Apr 12, 2026
497321a
ubusd_acl: fix NULL dereference on OOM in ubusd_acl_init
hauke Apr 12, 2026
f66d52b
ubusd_event: fix OOM handling in ubusd_send_event_msg
hauke Apr 12, 2026
11ea1b3
ubusd_main: fix async-signal-unsafe SIGHUP handler
hauke Apr 12, 2026
0c09559
ubusd_proto: fix resource leaks and ID tree corruption in ubusd_proto…
hauke Apr 12, 2026
f61695e
ubusd_proto: fix NULL dereference for user/group in ubusd_handle_add_…
hauke Apr 12, 2026
7ecacfa
ubusd_proto: fix NULL dereference on OOM in ubusd_proto_init_retmsg
hauke Apr 13, 2026
3ab9d77
lua: fix inverted argument check in ubus_lua_add
hauke Apr 12, 2026
43051ca
lua: fix unchecked calloc and memory leak in ubus_lua_load_object
hauke Apr 12, 2026
4ca0b14
ubusd_id: use getrandom(2) unconditionally on Linux
hauke Apr 12, 2026
7e4356d
ubusd_monitor: fix NULL dereference on OOM in ubusd_monitor_message
hauke Apr 16, 2026
5849870
libubus-req: fix file descriptor leaks in ubus_process_req_msg
hauke Apr 16, 2026
f29767f
libubus: fix file descriptor leaks in ubus_process_msg
hauke Apr 16, 2026
b099d05
libubus: make ubus_shutdown idempotent
hauke Apr 16, 2026
a564b8d
ubusd_main: check strdup return value in mkdir_sockdir
hauke Apr 16, 2026
239edcb
ubusd_id: fix continue in do-while skipping random ID retry
hauke May 3, 2026
09d2df4
ubusd: fix NULL dereference on OOM in ubus_msg_enqueue
hauke May 3, 2026
bcc45ca
libubus: actually set FD_CLOEXEC on the ubus socket
hauke May 3, 2026
8188f5c
libubus-io: close recv_fd captured before get_next_msg failure
hauke May 3, 2026
7a068ba
libubus-io: byte-swap peer in HELLO when storing as local_id
hauke May 3, 2026
747013f
libubus-io: reset sock.fd to -1 after close on ubus_reconnect error path
hauke May 3, 2026
020a64b
ubusd_acl: use size_t for strlen result in ubusd_acl_alloc_obj
hauke May 21, 2026
f92ffd2
ubusd: use size_t for string and blob length variables
hauke May 21, 2026
795b32b
ubusd: use fixed-width types for sequence counters
hauke May 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions libubus-acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ static void acl_recv_cb(struct ubus_request *req,
struct blob_attr *cur;
size_t rem;

struct blob_attr *new_blob = blob_memdup(msg);
if (!new_blob)
return;

if (acl_blob) {
struct acl_object *p, *q;

Expand All @@ -113,9 +117,9 @@ static void acl_recv_cb(struct ubus_request *req,
}
free(acl_blob);
}
acl_blob = blob_memdup(msg);
blobmsg_parse(acl_policy, __ACL_POLICY_MAX, tb, blobmsg_data(msg),
blobmsg_data_len(msg));
acl_blob = new_blob;
blobmsg_parse(acl_policy, __ACL_POLICY_MAX, tb, blobmsg_data(acl_blob),
blobmsg_data_len(acl_blob));

if (!tb[ACL_POLICY_SEQ] && !tb[ACL_POLICY_ACL])
return;
Expand Down
23 changes: 19 additions & 4 deletions libubus-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,19 @@ void __hidden ubus_handle_data(struct uloop_fd *u, unsigned int events)
if (!get_next_msg(ctx, &recv_fd))
break;
ubus_process_msg(ctx, &ctx->msgbuf, recv_fd);
recv_fd = -1;
if (uloop_cancelling() || ctx->cancel_poll)
break;
}

/*
* If get_next_msg() captured an fd via the header recvmsg but then
* failed (header validate, body recv, alloc), the fd is sitting in
* recv_fd unowned by anyone — close it instead of leaking.
*/
if (recv_fd >= 0)
close(recv_fd);

if (!ctx->stack_depth)
ctx->pending_timer.cb(&ctx->pending_timer);

Expand Down Expand Up @@ -439,20 +448,26 @@ int ubus_reconnect(struct ubus_context *ctx, const char *path)
if (read(ctx->sock.fd, blob_data(buf), blob_len(buf)) != (ssize_t) blob_len(buf))
goto out_free;

ctx->local_id = hdr.hdr.peer;
ctx->local_id = be32_to_cpu(hdr.hdr.peer);
if (ctx->local_id <= UBUS_CLIENT_ID_CHANNEL)
goto out_free;

ret = UBUS_STATUS_OK;
fcntl(ctx->sock.fd, F_SETFL, fcntl(ctx->sock.fd, F_GETFL) | O_NONBLOCK | O_CLOEXEC);
int flags = fcntl(ctx->sock.fd, F_GETFL);
if (flags < 0 ||
fcntl(ctx->sock.fd, F_SETFL, flags | O_NONBLOCK) < 0 ||
fcntl(ctx->sock.fd, F_SETFD, FD_CLOEXEC) < 0)
goto out_free;

ret = UBUS_STATUS_OK;
ubus_refresh_state(ctx);

out_free:
free(buf);
out_close:
if (ret)
if (ret) {
close(ctx->sock.fd);
ctx->sock.fd = -1;
}

return ret;
}
9 changes: 6 additions & 3 deletions libubus-req.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,10 +487,10 @@ void __hidden ubus_process_req_msg(struct ubus_context *ctx, struct ubus_msghdr_
break;

if (fd >= 0) {
if (req->fd_cb)
if (req->fd_cb) {
req->fd_cb(req, fd);
else
close(fd);
fd = -1;
}
}

if (id >= 0)
Expand All @@ -505,6 +505,9 @@ void __hidden ubus_process_req_msg(struct ubus_context *ctx, struct ubus_msghdr_
ubus_process_req_data(req, buf);
break;
}

if (fd >= 0)
close(fd);
}

int __ubus_monitor(struct ubus_context *ctx, const char *type)
Expand Down
29 changes: 24 additions & 5 deletions libubus.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,19 @@ const char *ubus_strerror(int error)
return err;
}

/*
* Note: any SCM_RIGHTS fd attached to the original message is not propagated
* to the queued copy — the caller must close it (or hand it off) separately.
*/
static void
ubus_queue_msg(struct ubus_context *ctx, struct ubus_msghdr_buf *buf)
{
struct ubus_pending_msg *pending;
void *data;

pending = calloc_a(sizeof(*pending), &data, blob_raw_len(buf->data));
if (!pending)
return;

pending->hdr.data = data;
memcpy(&pending->hdr.hdr, &buf->hdr, sizeof(buf->hdr));
Expand All @@ -97,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:
Expand All @@ -113,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;
Expand All @@ -122,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)
Expand Down Expand Up @@ -347,14 +356,20 @@ int ubus_channel_connect(struct ubus_context *ctx, int fd,
close(ctx->sock.fd);
}

int flags = fcntl(fd, F_GETFL);
if (flags < 0 ||
fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0 ||
fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
ctx->sock.fd = -1;
return -1;
}

ctx->sock.eof = false;
ctx->sock.error = false;
ctx->sock.fd = fd;
ctx->local_id = UBUS_CLIENT_ID_CHANNEL;
ctx->request_handler = handler;

fcntl(ctx->sock.fd, F_SETFL, fcntl(ctx->sock.fd, F_GETFL) | O_NONBLOCK | O_CLOEXEC);

return 0;
}

Expand Down Expand Up @@ -438,9 +453,13 @@ void ubus_shutdown(struct ubus_context *ctx)
if (!ctx)
return;
uloop_fd_delete(&ctx->sock);
close(ctx->sock.fd);
if (ctx->sock.fd >= 0) {
close(ctx->sock.fd);
ctx->sock.fd = -1;
}
uloop_timeout_cancel(&ctx->pending_timer);
free(ctx->msgbuf.data);
ctx->msgbuf.data = NULL;
}

void ubus_free(struct ubus_context *ctx)
Expand Down
13 changes: 10 additions & 3 deletions lua/ubus.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ static struct ubus_object* ubus_lua_load_object(lua_State *L)
{
struct ubus_lua_object *obj = NULL;
int mlen = lua_gettablelen(L, -1);
struct ubus_method *m;
struct ubus_method *m = NULL;
int midx = 0;

/* setup object pointers */
Expand All @@ -502,12 +502,19 @@ static struct ubus_object* ubus_lua_load_object(lua_State *L)
obj->o.name = lua_tostring(L, -2);

/* setup method pointers */
m = calloc(mlen, sizeof(struct ubus_method));
if (mlen > 0) {
m = calloc(mlen, sizeof(struct ubus_method));
if (!m) {
free(obj);
return NULL;
}
}
obj->o.methods = m;

/* setup type pointers */
obj->o.type = calloc(1, sizeof(struct ubus_object_type));
if (!obj->o.type) {
free(m);
free(obj);
return NULL;
}
Expand Down Expand Up @@ -559,7 +566,7 @@ static int ubus_lua_add(lua_State *L)
struct ubus_lua_connection *c = luaL_checkudata(L, 1, METANAME);

/* verify top level object */
if (lua_istable(L, 1)) {
if (!lua_istable(L, 2)) {
lua_pushstring(L, "you need to pass a table");
return lua_error(L);
}
Expand Down
4 changes: 4 additions & 0 deletions ubusd.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ static void ubus_msg_enqueue(struct ubus_client *cl, struct ubus_msg_buf *ub)

INIT_LIST_HEAD(&ubl->list);
ubl->msg = ubus_msg_ref(ub);
if (!ubl->msg) {
free(ubl);
return;
}

list_add_tail(&ubl->list, &cl->tx_queue);
cl->txq_len += ub->len + sizeof(ub->hdr);
Expand Down
31 changes: 26 additions & 5 deletions ubusd_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct ubusd_acl_file {
const char *ubusd_acl_dir = "/usr/share/acl.d";
static struct blob_buf bbuf;
static struct avl_tree ubusd_acls;
static int ubusd_acl_seq;
static uint32_t ubusd_acl_seq;
static struct ubus_object *acl_obj;

static int
Expand Down Expand Up @@ -191,7 +191,7 @@ ubusd_acl_load_extra_gids(struct ubus_client *cl, pid_t pid)
snprintf(path, sizeof(path), "/proc/%d/status", (int)pid);
f = fopen(path, "r");
if (!f)
return -1;
return 0;

while (fgets(line, sizeof(line), f)) {
if (strncmp(line, "Groups:", 7) != 0)
Expand Down Expand Up @@ -257,9 +257,27 @@ ubusd_acl_init_client(struct ubus_client *cl, int fd)
cl->gid = cred.gid;

cl->group = strdup(group->gr_name);
if (!cl->group) {
ULOG_ERR("Failed strdup() for group\n");
return -1;
}

cl->user = strdup(pwd->pw_name);
if (!cl->user) {
ULOG_ERR("Failed strdup() for user\n");
free(cl->group);
cl->group = NULL;
return -1;
}

ubusd_acl_load_extra_gids(cl, cred.pid);
if (ubusd_acl_load_extra_gids(cl, cred.pid)) {
ULOG_ERR("Failed to load extra gids\n");
free(cl->user);
cl->user = NULL;
free(cl->group);
cl->group = NULL;
return -1;
}

return 0;
}
Expand Down Expand Up @@ -303,7 +321,7 @@ static struct ubusd_acl_obj*
ubusd_acl_alloc_obj(struct ubusd_acl_file *file, const char *obj)
{
struct ubusd_acl_obj *o;
int len = strlen(obj);
size_t len = strlen(obj);
char *k;
bool partial = false;

Expand All @@ -316,6 +334,8 @@ ubusd_acl_alloc_obj(struct ubusd_acl_file *file, const char *obj)
}

o = calloc_a(sizeof(*o), &k, len + 1);
if (!o)
return NULL;
o->partial = partial;
o->user = file->user;
o->group = file->group;
Expand Down Expand Up @@ -666,5 +686,6 @@ void ubusd_acl_init(void)
{
ubus_init_string_tree(&ubusd_acls, true);
acl_obj = ubusd_create_object_internal(NULL, UBUS_SYSTEM_OBJECT_ACL);
acl_obj->recv_msg = ubusd_acl_recv;
if (acl_obj)
acl_obj->recv_msg = ubusd_acl_recv;
}
Loading
Loading