service: fix double-free in error path
[project/procd.git] / service / service.c
index 4153fec..bfc8d49 100644 (file)
@@ -117,10 +117,9 @@ service_update(struct service *s, struct blob_attr *config, struct blob_attr **t
        service_validate_del(s);
 
        if (tb[SERVICE_SET_TRIGGER] && blobmsg_data_len(tb[SERVICE_SET_TRIGGER])) {
-               s->trigger = malloc(blob_pad_len(tb[SERVICE_SET_TRIGGER]));
+               s->trigger = blob_memdup(tb[SERVICE_SET_TRIGGER]);
                if (!s->trigger)
                        return -1;
-               memcpy(s->trigger, tb[SERVICE_SET_TRIGGER], blob_pad_len(tb[SERVICE_SET_TRIGGER]));
                trigger_add(s->trigger, s);
        }
 
@@ -139,7 +138,7 @@ service_update(struct service *s, struct blob_attr *config, struct blob_attr **t
                        vlist_flush(&s->instances);
        }
 
-       rcnow(s->name, "running");
+       rc(s->name, "running");
 
        return 0;
 }
@@ -217,13 +216,13 @@ service_handle_set(struct ubus_context *ctx, struct ubus_object *obj,
        struct blob_attr *tb[__SERVICE_SET_MAX], *cur;
        struct service *s = NULL;
        const char *name;
-       int ret = UBUS_STATUS_INVALID_ARGUMENT;
        bool add = !strcmp(method, "add");
+       int ret;
 
        blobmsg_parse(service_set_attrs, __SERVICE_SET_MAX, tb, blob_data(msg), blob_len(msg));
        cur = tb[SERVICE_ATTR_NAME];
        if (!cur)
-               goto free;
+               return UBUS_STATUS_INVALID_ARGUMENT;
 
        name = blobmsg_data(cur);
 
@@ -240,15 +239,11 @@ service_handle_set(struct ubus_context *ctx, struct ubus_object *obj,
 
        ret = service_update(s, msg, tb, add);
        if (ret)
-               goto free;
+               return ret;
 
        avl_insert(&services, &s->avl);
 
        return 0;
-
-free:
-       free(msg);
-       return ret;
 }
 
 static void
@@ -259,15 +254,12 @@ service_dump(struct service *s, int verbose)
 
        c = blobmsg_open_table(&b, s->name);
 
-       if (avl_is_empty(&s->instances.avl)) {
-               blobmsg_close_table(&b, c);
-               return;
+       if (!avl_is_empty(&s->instances.avl)) {
+               i = blobmsg_open_table(&b, "instances");
+               vlist_for_each_element(&s->instances, in, node)
+                       instance_dump(&b, in, verbose);
+               blobmsg_close_table(&b, i);
        }
-
-       i = blobmsg_open_table(&b, "instances");
-       vlist_for_each_element(&s->instances, in, node)
-               instance_dump(&b, in, verbose);
-       blobmsg_close_table(&b, i);
        if (verbose && s->trigger)
                blobmsg_add_blob(&b, s->trigger);
        if (verbose && !list_empty(&s->validators))
@@ -446,9 +438,9 @@ service_start_early(char *name, char *cmdline)
        }
        blobmsg_close_array(&b, command);
        respawn = blobmsg_open_array(&b, "respawn");
-       blobmsg_add_string(&b, NULL, "1");
        blobmsg_add_string(&b, NULL, "3600");
-       blobmsg_add_string(&b, NULL, "10");
+       blobmsg_add_string(&b, NULL, "1");
+       blobmsg_add_string(&b, NULL, "0");
        blobmsg_close_array(&b, respawn);
        blobmsg_close_table(&b, instance);
        blobmsg_close_table(&b, instances);