summaryrefslogtreecommitdiff
path: root/ubusd.c
diff options
context:
space:
mode:
authorAlexandru Ardelean <ardeleanalex@gmail.com>2014-06-27 19:11:43 +0300
committerFelix Fietkau <nbd@openwrt.org>2014-07-03 12:45:49 +0200
commit996e16b2cb79ae3e46742285ee2728f3a166b42a (patch)
tree5bf1e42bc4c88e1a75186500104f0958fc0f383d /ubusd.c
parent5db90dbc941da701c397b04ddce2515a231df59b (diff)
downloadubus-996e16b2cb79ae3e46742285ee2728f3a166b42a.tar.gz
ubusd: replace ubusd_msg_unshare() with ubus_msg_new() to prevent invalid free-ing
The realloc is problematic mostly with large packets, as the pointer changes so what eventually gets free'd is invalid. Note that ub ptr param in the call will be passed on to a ubus_msg_free(), right after ubus_msg_ref() finishes. This bug stayed hidden the same way as the bug in libubus writev_retry(). Since the write/sendmsg function can send about ~200k the ubus_msg_enqueue() call does not get triggered.
Diffstat (limited to 'ubusd.c')
-rw-r--r--ubusd.c14
1 files changed, 1 insertions, 13 deletions
diff --git a/ubusd.c b/ubusd.c
index bcc8603..8903105 100644
--- a/ubusd.c
+++ b/ubusd.c
@@ -29,22 +29,10 @@
#include "ubusd.h"
-static struct ubus_msg_buf *ubus_msg_unshare(struct ubus_msg_buf *ub)
-{
- ub = realloc(ub, sizeof(*ub) + ub->len);
- if (!ub)
- return NULL;
-
- ub->refcount = 1;
- memcpy(ub + 1, ub->data, ub->len);
- ub->data = (void *) (ub + 1);
- return ub;
-}
-
static struct ubus_msg_buf *ubus_msg_ref(struct ubus_msg_buf *ub)
{
if (ub->refcount == ~0)
- return ubus_msg_unshare(ub);
+ return ubus_msg_new(ub->data, ub->len, false);
ub->refcount++;
return ub;