file: exec: properly free memory on error
[project/rpcd.git] / plugin.c
index b75241aae1f82ce0a84b5d40c1c74b2e8c0577ed..4f84994c107f40269e8b4aba9146cc82632b0048 100644 (file)
--- a/plugin.c
+++ b/plugin.c
@@ -135,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);
@@ -161,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);
 
@@ -321,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;
 
@@ -402,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
@@ -410,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;