Commit graph

25 commits

Author SHA1 Message Date
Daniel Danzberger
9913aa61de ubusd: add lookup command queuing support
Defers and continues a client's lookup command to avoid unnecessary
buffering under load.

Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2022-06-15 19:59:40 +02:00
Arnout Vandecappelle (Essensium/Mind)
c736e47f3e ubusd: add per-client tx queue limit
No new message can be enqueued if this brings the total queue length of
that client over UBUS_CLIENT_MAX_TXQ_LEN.

Set UBUS_CLIENT_MAX_TXQ_LEN to UBUS_MAX_MSGLEN, i.e. 1MB. This limit
should be plenty for any practical use case.

Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
2021-05-31 18:39:31 +02:00
Arnout Vandecappelle (Essensium/Mind)
4becbd67de ubusd: convert tx_queue to linked list
ubusd maintains a per-client tx_queue containing references to message
buffers that have not been sent yet (due to the socket blocking). This
is a fixed-size, 64-element queue.

When more than 64 elements are queued, subsequent elements are simply
dropped. Thus, a client that is waiting for those messages will block
indefinitely. In particular, this happens when more than +- 250 objects
are registered on the bus and either "ubus list" or "ubus wait_for" is
called. The responses to these requests consist of a message buffer per
object. Since in practice, ubusd will not yield between the sends of
these message buffers, the client has no time to process them and
eventually the output socket blocks. After 64 more objects, the rest is
dropped, including the final message that indicates termination. Thus,
the client waits indefinitely for the termination message.

To solve this, turn the tx_queue into a variable-sized linked list
instead of a fixed-size queue.

To maintain the linked list, an additional structure ubus_msg_buf_list
is created. It is not possible to add the linked list to ubus_msg_buf,
because that is shared between clients.

Note that this infinite tx_queue opens the door to a DoS attack. You can
open a client and a server connection, then send messages from the
client to the server without ever reading anything on the server side.
This will eventually lead to an out-of-memory. However, such a DoS
already existed anyway, it just requires opening multiple server
connections and filling up the fixed-size queue on each one. To protect
against such DoS attacks, we'd need to:
- keep a global maximum queue size that applies to all rx and tx queues
  together;
- stop reading from any connection when the maximum is reached;
- close any connection when it hasn't become writeable after some
  timeout.

Fixes: https://bugs.openwrt.org/index.php?do=details&task_id=1525

Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
2021-05-31 14:16:19 +02:00
Petr Štetiar
a1523d76b0 fix blob parsing vulnerability by using blob_parse_untrusted
blob_parse expects blobs from trusted inputs, but it can be supplied
with possibly malicious blobs from untrusted inputs as well, which might
lead to undefined behaviour and/or crash of ubus daemon. In order to
prevent such conditions, switch to blob_parse_untrusted which should
hopefully handle such untrusted inputs appropriately.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
2019-12-19 19:53:25 +01:00
Petr Štetiar
c413be9b37 refactor ubusd.c into reusable ubusd_library
In order to allow reusability in unit testing & fuzzing.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
2019-12-16 23:39:16 +01:00
Alexandru Ardelean
5f87f5480e ubusd: move global retmsg per client
Even with the tx_queue-ing issue resolved, what
seems to happen afterwards, is that all the messages
seems to get through, but the client still loops
in the `ubus_complete_request()` waiting for
`req->status_msg` or for a timeout.

Though, the timeout does not seem to happen, because
the data is processed in `ubus_poll_data()`, with
a infinite poll() timeout (ubus_complete_request() is
called with timeout 0).

It's likely that either the `seq` or `peer` sent from
ubusd are wrong, and the client cannot get the correct
ubus request in `ubus_process_req_msg()`.
I haven't digged too deep into this ; setting the
`retmsg` object on the client struct seems to have
resolved any hanging with the `ubus list` command.

Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name> [fix placement of retmsg in cl]
2017-11-13 10:09:28 +01:00
Alexandru Ardelean
e02813b2cc ubusd: don't free messages in ubus_send_msg() anymore
This makes it clear that `ubus_msg_send()` is only
about sending and queue-ing messages, and has nothing
to do with free-ing.

It can be a bit misleading/confusing when trying to go
through the code and make assumptions about whether a
buffer is free'd in ubus_send_msg(), or is free'd outside.

In `ubusd_proto_receive_message()` the `ubus_msg_free()`
is now called before the `if (ret == -1)` check.
That way, all callbacks will have their messages free'd,
which is what's desired, but confusing, because:
* ubusd_handle_invoke() called ubus_msg_free() before returning -1
* ubusd_handle_notify() called ubus_msg_free() before returning -1
* ubusd_handle_response() called ubus_msg_send(,,free=true) before returning -1
* ubus_msg_send() would call ubus_msg_send(,,free=false)
* all other callback callers would `ubus_msg_send(,,free=true)`
  (free the buffers in ubus_msg_send() )

In all other places, where `ubus_msg_send(,,free=true)`
an explicit `ubus_msg_free()` was added.

Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
2017-11-13 09:55:19 +01:00
Felix Fietkau
83461b9791 ubusd: make ACL path configurable on the command line
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2015-12-09 17:44:00 +01:00
Felix Fietkau
47d75dd84a ubusd: add monitor support
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2015-11-19 22:32:11 +01:00
John Crispin
8309c75828 add acl code
Signed-off-by: John Crispin <blogic@openwrt.org>
2015-06-18 19:01:17 +02:00
John Crispin
9ffec46f73 make ubus_proto_send_msg_from_blob() none static
Signed-off-by: John Crispin <blogic@openwrt.org>
2015-06-18 19:01:17 +02:00
John Crispin
8c992a556b make ubus_parse_msg() none static
Signed-off-by: John Crispin <blogic@openwrt.org>
2015-06-18 19:01:17 +02:00
John Crispin
0bb927125f make ubusd_send_event() none static
Signed-off-by: John Crispin <blogic@openwrt.org>
2015-06-18 19:01:17 +02:00
Felix Fietkau
37cc5d2f25 ubusd: implement protocol support for passing file descriptors as part of request completion msgs from objects to clients
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2014-02-18 15:03:53 +01:00
Felix Fietkau
42bc27ae38 add copyright/license information 2011-06-17 16:35:11 +02:00
Felix Fietkau
0611a9248c add notifications for registered/unregistered objects with path 2011-02-10 01:31:52 +01:00
Felix Fietkau
37e914937b move more protocol related stuff to ubusd_proto.c 2011-02-07 02:59:09 +01:00
Felix Fietkau
faedeaaca8 make ubus_msg_ref static 2011-02-07 02:41:56 +01:00
Felix Fietkau
1643f728e7 make ubusd_get_client_by_id static 2011-02-07 02:40:40 +01:00
Felix Fietkau
c4c0a2256d make ubus_parse_msg static 2011-02-07 02:38:57 +01:00
Felix Fietkau
f9f602533a add code for sending events and fix the code for receiving events 2011-02-07 01:25:28 +01:00
Felix Fietkau
da11ec6b9d remove duplicate definition of UBUS_UNIX_SOCKET 2011-02-06 20:55:34 +01:00
Felix Fietkau
a84c6cac9a fix message buffering 2011-02-05 20:50:08 +01:00
Felix Fietkau
fa989780bd add some stub functionality for the ubus event switch 2011-02-05 01:29:52 +01:00
Felix Fietkau
dbd4c2f121 Initial import 2011-01-30 14:16:09 +01:00