file: exec: properly free memory on error
[project/rpcd.git] / plugin.c
index ba8d8db44d2f554b202ca25558899d6195321dac..4f84994c107f40269e8b4aba9146cc82632b0048 100644 (file)
--- a/plugin.c
+++ b/plugin.c
@@ -1,7 +1,7 @@
 /*
  * rpcd - UBUS RPC server
  *
- *   Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
+ *   Copyright (C) 2013-2014 Jo-Philipp Wich <jow@openwrt.org>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -108,12 +108,9 @@ rpc_plugin_call_finish_cb(struct blob_buf *blob, int stat, void *priv)
        {
                if (c->obj)
                {
-                       if (json_object_get_type(c->obj) == json_type_object ||
-                           json_object_get_type(c->obj) == json_type_array)
-                       {
-                               blobmsg_add_json_element(blob, NULL, c->obj);
+                       if (json_object_get_type(c->obj) == json_type_object &&
+                           blobmsg_add_object(blob, c->obj))
                                rv = UBUS_STATUS_OK;
-                       }
 
                        json_object_put(c->obj);
                }
@@ -138,18 +135,18 @@ rpc_plugin_call(struct ubus_context *ctx, struct ubus_object *obj,
 {
        int rv = UBUS_STATUS_UNKNOWN_ERROR;
        struct call_context *c;
-       char *plugin;
+       char *plugin, *mptr;
 
-       c = calloc(1, sizeof(*c));
+       c = calloc_a(sizeof(*c), &mptr, strlen(method) + 1);
 
        if (!c)
                goto fail;
 
-       c->method = strdup(method);
+       c->method = strcpy(mptr, method);
        c->input = blobmsg_format_json(msg, true);
        c->tok = json_tokener_new();
 
-       if (!c->method || !c->input || !c->tok)
+       if (!c->input || !c->tok)
                goto fail;
 
        plugin = c->path + sprintf(c->path, "%s/", RPC_PLUGIN_DIRECTORY);
@@ -164,16 +161,16 @@ rpc_plugin_call(struct ubus_context *ctx, struct ubus_object *obj,
        c->argv[1] = "call";
        c->argv[2] = c->method;
 
-       return rpc_exec(c->argv, rpc_plugin_call_stdin_cb,
-                       rpc_plugin_call_stdout_cb, rpc_plugin_call_stderr_cb,
-                       rpc_plugin_call_finish_cb, c, ctx, req);
+       rv = rpc_exec(c->argv, rpc_plugin_call_stdin_cb,
+                     rpc_plugin_call_stdout_cb, rpc_plugin_call_stderr_cb,
+                     rpc_plugin_call_finish_cb, c, ctx, req);
+
+       if (rv == UBUS_STATUS_OK)
+               return rv;
 
 fail:
        if (c)
        {
-               if (c->method)
-                       free(c->method);
-
                if (c->input)
                        free(c->input);
 
@@ -324,10 +321,17 @@ rpc_plugin_parse_exec(const char *name, int fd)
 
        obj_type = calloc(1, sizeof(*obj_type));
 
-       if (!obj_type)
+       if (!obj_type) {
+               free(obj);
                return NULL;
+       }
+
+       if (asprintf((char **)&obj_type->name, "luci-rpc-plugin-%s", name) < 0) {
+               free(obj);
+               free(obj_type);
+               return NULL;
+       }
 
-       asprintf((char **)&obj_type->name, "luci-rpc-plugin-%s", name);
        obj_type->methods = methods;
        obj_type->n_methods = n_method;
 
@@ -405,6 +409,7 @@ static const struct rpc_daemon_ops ops = {
        .session_create_cb  = rpc_session_create_cb,
        .session_destroy_cb = rpc_session_destroy_cb,
        .exec               = rpc_exec,
+       .exec_timeout       = &rpc_exec_timeout,
 };
 
 static int
@@ -413,7 +418,7 @@ rpc_plugin_register_library(struct ubus_context *ctx, const char *path)
        struct rpc_plugin *p;
        void *dlh;
 
-       dlh = dlopen(path, RTLD_LAZY | RTLD_GLOBAL);
+       dlh = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
 
        if (!dlh)
                return UBUS_STATUS_UNKNOWN_ERROR;