hotplug-dispatch: fix rare memory leaks in error paths
authorDaniel Golle <daniel@makrotopia.org>
Wed, 4 Aug 2021 20:13:32 +0000 (21:13 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Thu, 5 Aug 2021 02:26:18 +0000 (03:26 +0100)
Fix remaining memory leaks in error paths.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
hotplug-dispatch.c

index 70ec5df5004d8b47c22a5abdd46cbd4b26d5f3b7..cfba7d19b745725bbf0e81eadd9639055e4b45c7 100644 (file)
@@ -123,6 +123,7 @@ static void hotplug_exec(struct uloop_timeout *t)
                exit(execve(exec_argv[0], exec_argv, pc->envp));
        } else if (pc->process.pid < 0) {
                /* fork error */
+               free(script);
                hotplug_free(pc);
                return;
        }
@@ -187,6 +188,7 @@ static int hotplug_call(struct ubus_context *ctx, struct ubus_object *obj,
        size_t envz = 0;
        struct hotplug_process *pc;
        bool async = true;
+       int err = UBUS_STATUS_UNKNOWN_ERROR;
 
        blobmsg_parse(hotplug_policy, __HOTPLUG_MAX, tb, blobmsg_data(msg), blobmsg_len(msg));
 
@@ -208,6 +210,7 @@ static int hotplug_call(struct ubus_context *ctx, struct ubus_object *obj,
                }
                envle->avl.key = envle->env;
                if (avl_insert(&env, &envle->avl) == -1) {
+                       free(envle->env);
                        free(envle);
                        goto err_envle;
                }
@@ -261,6 +264,12 @@ static int hotplug_call(struct ubus_context *ctx, struct ubus_object *obj,
                }
        }
 
+       /* synchronous calls are unsupported for now */
+       if (!async) {
+               err = UBUS_STATUS_NOT_SUPPORTED;
+               goto err_envle;
+       }
+
        /* allocating new environment */
        avl_for_each_element(&env, envle, avl)
                ++envz;
@@ -277,18 +286,6 @@ static int hotplug_call(struct ubus_context *ctx, struct ubus_object *obj,
                free(envle);
        }
 
-       /* glob'ing for hotplug scripts */
-       if (asprintf(&globstr, "%s/%s/*", HOTPLUG_BASEDIR, subsys) == -1) {
-               env_free(envp);
-               return UBUS_STATUS_UNKNOWN_ERROR;
-       }
-
-       /* synchronous calls are unsupported for now */
-       if (!async) {
-               env_free(envp);
-               return UBUS_STATUS_NOT_SUPPORTED;
-       }
-
        pc = calloc(1, sizeof(struct hotplug_process));
        if (!pc) {
                env_free(envp);
@@ -299,6 +296,12 @@ static int hotplug_call(struct ubus_context *ctx, struct ubus_object *obj,
        pc->cnt = 0;
        pc->ubus = obj;
 
+       /* glob'ing for hotplug scripts */
+       if (asprintf(&globstr, "%s/%s/*", HOTPLUG_BASEDIR, subsys) == -1) {
+               env_free(envp);
+               return UBUS_STATUS_UNKNOWN_ERROR;
+       }
+
        if (glob(globstr, GLOB_DOOFFS, NULL, &pc->globbuf)) {
                free(globstr);
                hotplug_free(pc);
@@ -321,7 +324,7 @@ err_envle:
                free(envle);
        }
 
-       return UBUS_STATUS_UNKNOWN_ERROR;
+       return err;
 }
 
 static const struct ubus_method hotplug_methods[] = {