]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
{machine,system}ctl: always pass &changes and &n_changes (#3350)
authorChristian Hesse <mail@eworm.de>
Thu, 26 May 2016 13:57:37 +0000 (15:57 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 26 May 2016 13:57:37 +0000 (15:57 +0200)
We have to pass addresses of changes and n_changes to
bus_deserialize_and_dump_unit_file_changes(). Otherwise we are hit by
missing information (subsequent calls to unit_file_changes_add() to
not add anything).

Also prevent null pointer dereference in
bus_deserialize_and_dump_unit_file_changes() by asserting.

Fixes #3339

src/machine/machinectl.c
src/shared/bus-unit-util.c
src/systemctl/systemctl.c

index 1165ab5afadce5151fead7282b72b400cbb37631..8e4ffa9a394a3cc2af557507839b8773eece29a7 100644 (file)
@@ -1602,6 +1602,8 @@ static int start_machine(int argc, char *argv[], void *userdata) {
 static int enable_machine(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
         int carries_install_info = 0;
         const char *method = NULL;
         sd_bus *bus = userdata;
@@ -1662,9 +1664,9 @@ static int enable_machine(int argc, char *argv[], void *userdata) {
                         return bus_log_parse_error(r);
         }
 
-        r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
+        r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
         if (r < 0)
-                return r;
+                goto finish;
 
         r = sd_bus_call_method(
                         bus,
@@ -1677,10 +1679,15 @@ static int enable_machine(int argc, char *argv[], void *userdata) {
                         NULL);
         if (r < 0) {
                 log_error("Failed to reload daemon: %s", bus_error_message(&error, -r));
-                return r;
+                goto finish;
         }
 
-        return 0;
+        r = 0;
+
+finish:
+        unit_file_changes_free(changes, n_changes);
+
+        return r;
 }
 
 static int match_log_message(sd_bus_message *m, void *userdata, sd_bus_error *error) {
index f6559cd854406367e01851e6cfd68bd9d95602a3..f68c4a41ac54b7de896a08ece592ccd2acf67da1 100644 (file)
@@ -865,6 +865,11 @@ int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, Un
         const char *type, *path, *source;
         int r;
 
+        /* changes is dereferenced when calling unit_file_dump_changes() later,
+         * so we have to make sure this is not NULL. */
+        assert(changes);
+        assert(n_changes);
+
         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
         if (r < 0)
                 return bus_log_parse_error(r);
index b943c68e1b6361dc052b2f77ad1fa6ac5b6e5696..0500593d0628ed1ffcdd4d5fbcde3f614efbee45 100644 (file)
@@ -2058,6 +2058,8 @@ static int get_default(int argc, char *argv[], void *userdata) {
 
 static int set_default(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *unit = NULL;
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
         int r;
 
         assert(argc >= 2);
@@ -2068,13 +2070,8 @@ static int set_default(int argc, char *argv[], void *userdata) {
                 return log_error_errno(r, "Failed to mangle unit name: %m");
 
         if (install_client_side()) {
-                UnitFileChange *changes = NULL;
-                unsigned n_changes = 0;
-
                 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
                 unit_file_dump_changes(r, "set default", changes, n_changes, arg_quiet);
-                unit_file_changes_free(changes, n_changes);
-                return r;
         } else {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
@@ -2098,9 +2095,9 @@ static int set_default(int argc, char *argv[], void *userdata) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to set default target: %s", bus_error_message(&error, r));
 
-                r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
+                r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
                 if (r < 0)
-                        return r;
+                        goto finish;
 
                 /* Try to reload if enabled */
                 if (!arg_no_reload)
@@ -2109,6 +2106,9 @@ static int set_default(int argc, char *argv[], void *userdata) {
                         r = 0;
         }
 
+finish:
+        unit_file_changes_free(changes, n_changes);
+
         return r;
 }
 
@@ -5650,6 +5650,8 @@ static int add_dependency(int argc, char *argv[], void *userdata) {
         _cleanup_strv_free_ char **names = NULL;
         _cleanup_free_ char *target = NULL;
         const char *verb = argv[0];
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
         UnitDependency dep;
         int r = 0;
 
@@ -5672,13 +5674,8 @@ static int add_dependency(int argc, char *argv[], void *userdata) {
                 assert_not_reached("Unknown verb");
 
         if (install_client_side()) {
-                UnitFileChange *changes = NULL;
-                unsigned n_changes = 0;
-
                 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
                 unit_file_dump_changes(r, "add dependency on", changes, n_changes, arg_quiet);
-                unit_file_changes_free(changes, n_changes);
-                return r;
         } else {
                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -5712,27 +5709,32 @@ static int add_dependency(int argc, char *argv[], void *userdata) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to add dependency: %s", bus_error_message(&error, r));
 
-                r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
+                r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
                 if (r < 0)
-                        return r;
+                        goto finish;
 
-                if (arg_no_reload)
-                        return 0;
-                return daemon_reload(argc, argv, userdata);
+                if (arg_no_reload) {
+                        r = 0;
+                        goto finish;
+                }
+
+                r = daemon_reload(argc, argv, userdata);
         }
+
+finish:
+        unit_file_changes_free(changes, n_changes);
+
+        return r;
 }
 
 static int preset_all(int argc, char *argv[], void *userdata) {
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
         int r;
 
         if (install_client_side()) {
-                UnitFileChange *changes = NULL;
-                unsigned n_changes = 0;
-
                 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
                 unit_file_dump_changes(r, "preset", changes, n_changes, arg_quiet);
-                unit_file_changes_free(changes, n_changes);
-                return r;
         } else {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
@@ -5759,14 +5761,22 @@ static int preset_all(int argc, char *argv[], void *userdata) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to preset all units: %s", bus_error_message(&error, r));
 
-                r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
+                r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
                 if (r < 0)
-                        return r;
+                        goto finish;
 
-                if (arg_no_reload)
-                        return 0;
-                return daemon_reload(argc, argv, userdata);
+                if (arg_no_reload) {
+                        r = 0;
+                        goto finish;
+                }
+
+                r = daemon_reload(argc, argv, userdata);
         }
+
+finish:
+        unit_file_changes_free(changes, n_changes);
+
+        return r;
 }
 
 static int unit_is_enabled(int argc, char *argv[], void *userdata) {