diff -Nru systemd-229/debian/changelog systemd-229/debian/changelog --- systemd-229/debian/changelog 2019-03-29 16:43:00.000000000 +0000 +++ systemd-229/debian/changelog 2019-05-16 15:14:59.000000000 +0100 @@ -1,3 +1,13 @@ +systemd (229-4ubuntu21.22) xenial; urgency=medium + + * d/p/systemctl-Replace-check_one_unit-by-get_state_one_un.patch + - Backport upstream PR#2768 needed for next patch + * d/p/systemctl-load-unit-if-needed-in-systemctl-is-active.patch + - Backport upstream PR#7997 to fix alias service reports inactive while + aliased is active (LP: #1828892) + + -- Ioanna Alifieraki Thu, 16 May 2019 15:08:18 +0100 + systemd (229-4ubuntu21.21) xenial-security; urgency=medium * SECURITY UDPATE: Unsafe environment usage in pam_systemd.so leads to diff -Nru systemd-229/debian/patches/series systemd-229/debian/patches/series --- systemd-229/debian/patches/series 2019-03-29 16:43:00.000000000 +0000 +++ systemd-229/debian/patches/series 2019-05-16 15:04:44.000000000 +0100 @@ -137,3 +137,5 @@ fix-race-daemon-reload-11121.patch virt-detect-WSL-environment-as-a-container-id-wsl.patch CVE-2019-3842.patch +systemctl-Replace-check_one_unit-by-get_state_one_un.patch +systemctl-load-unit-if-needed-in-systemctl-is-active.patch diff -Nru systemd-229/debian/patches/systemctl-load-unit-if-needed-in-systemctl-is-active.patch systemd-229/debian/patches/systemctl-load-unit-if-needed-in-systemctl-is-active.patch --- systemd-229/debian/patches/systemctl-load-unit-if-needed-in-systemctl-is-active.patch 1970-01-01 01:00:00.000000000 +0100 +++ systemd-229/debian/patches/systemctl-load-unit-if-needed-in-systemctl-is-active.patch 2019-05-16 15:07:25.000000000 +0100 @@ -0,0 +1,108 @@ +From: Lennart Poettering +Origin: Upstream, https://github.com/systemd/systemd/pull/7997 +Bug: https://github.com/systemd/systemd/issues/7875 +Bug-Ubuntu: https://launchpad.net/bugs/1828892 +Date: Thu, 25 Jan 2018 15:14:25 +0100 +Subject: [PATCH] systemctl: load unit if needed in "systemctl is-active" + +Previously, we'd explicitly use "GetUnit()" on the server side to +convert a unit name into a bus path, as that function will return an +error if the unit is not currently loaded. If we'd convert the path on +the client side, and access the unit this way directly the unit would be +loaded automatically in the background. + +The old logic was done in order to minimize the effect of "is-active" on +the system, i.e. that a monoitoring command does not itself alter the +state of the system. + +however, this is problematic as this can lead to confusing results if +the queried unit name is an alias that currently is not loaded: we'd +claim the unit wasn't active even though this isn't strictly true: the +unit the name is an alias for might be. + +Hence, let's simplify the code, and accept that we might end up loading +a unit briefly here, and let's make "systemctl is-active" skip the +GetUnit() thing and calculate the unit path right away. + +Fixes: #7875 +--- + src/systemctl/systemctl.c | 55 ++++++++++++--------------------------- + 1 file changed, 16 insertions(+), 39 deletions(-) + +Index: systemd-229/src/systemctl/systemctl.c +=================================================================== +--- systemd-229.orig/src/systemctl/systemctl.c ++++ systemd-229/src/systemctl/systemctl.c +@@ -2426,55 +2426,32 @@ static int unit_find_paths( + + static int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *active_state) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; +- _cleanup_free_ char *buf = NULL; ++ _cleanup_free_ char *buf = NULL, *path = NULL; + UnitActiveState state; +- const char *path; + int r; + + assert(name); + assert(active_state); + +- /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it +- * isn't loaded. */ +- r = sd_bus_call_method( ++ path = unit_dbus_path_from_name(name); ++ if (!path) ++ return log_oom(); ++ ++ r = sd_bus_get_property_string( + bus, + "org.freedesktop.systemd1", +- "/org/freedesktop/systemd1", +- "org.freedesktop.systemd1.Manager", +- "GetUnit", ++ path, ++ "org.freedesktop.systemd1.Unit", ++ "ActiveState", + &error, +- &reply, +- "s", name); +- if (r < 0) { +- if (!sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT)) +- return log_error_errno(r, "Failed to retrieve unit: %s", bus_error_message(&error, r)); +- +- /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are +- * considered inactive. */ +- state = UNIT_INACTIVE; +- +- } else { +- r = sd_bus_message_read(reply, "o", &path); +- if (r < 0) +- return bus_log_parse_error(r); +- +- r = sd_bus_get_property_string( +- bus, +- "org.freedesktop.systemd1", +- path, +- "org.freedesktop.systemd1.Unit", +- "ActiveState", +- &error, +- &buf); +- if (r < 0) +- return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r)); +- +- state = unit_active_state_from_string(buf); +- if (state == _UNIT_ACTIVE_STATE_INVALID) { +- log_error("Invalid unit state '%s' for: %s", buf, name); +- return -EINVAL; +- } ++ &buf); ++ if (r < 0) ++ return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r)); ++ ++ state = unit_active_state_from_string(buf); ++ if (state == _UNIT_ACTIVE_STATE_INVALID) { ++ log_error("Invalid unit state '%s' for: %s", buf, name); ++ return -EINVAL; + } + + *active_state = state; diff -Nru systemd-229/debian/patches/systemctl-Replace-check_one_unit-by-get_state_one_un.patch systemd-229/debian/patches/systemctl-Replace-check_one_unit-by-get_state_one_un.patch --- systemd-229/debian/patches/systemctl-Replace-check_one_unit-by-get_state_one_un.patch 1970-01-01 01:00:00.000000000 +0100 +++ systemd-229/debian/patches/systemctl-Replace-check_one_unit-by-get_state_one_un.patch 2019-05-16 15:03:47.000000000 +0100 @@ -0,0 +1,211 @@ +From: Benjamin ROBIN +Origin: Upstream, https://github.com/systemd/systemd/pull/2768 +Bug: https://github.com/systemd/systemd/issues/2718 +Bug-Ubuntu: https://launchpad.net/bugs/1828892 +Date: Mon, 29 Feb 2016 14:25:16 +0100 +Subject: [PATCH] systemctl: Replace check_one_unit() by get_state_one_unit() + +The get_state_one_unit returns the enum of the active state of the unit +Do not rely on the string value of the active state. + +Fix #2718 since the refactoring allow to handle more case +--- + src/systemctl/systemctl.c | 84 +++++++++++++++++++++++++-------------- + 1 file changed, 55 insertions(+), 29 deletions(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index a4491692a9..8e39b7a342 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -152,7 +152,7 @@ static bool arg_now = false; + + static int daemon_reload(int argc, char *argv[], void* userdata); + static int halt_now(enum action a); +-static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet); ++static int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *active_state); + + static bool original_stdout_is_tty; + +@@ -1630,11 +1630,27 @@ static int list_dependencies_one( + if (arg_plain) + printf(" "); + else { +- int state; ++ UnitActiveState active_state = _UNIT_ACTIVE_STATE_INVALID; + const char *on; + +- state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true); +- on = state > 0 ? ansi_highlight_green() : ansi_highlight_red(); ++ (void) get_state_one_unit(bus, *c, &active_state); ++ switch (active_state) { ++ case UNIT_ACTIVE: ++ case UNIT_RELOADING: ++ case UNIT_ACTIVATING: ++ on = ansi_highlight_green(); ++ break; ++ ++ case UNIT_INACTIVE: ++ case UNIT_DEACTIVATING: ++ on = ansi_normal(); ++ break; ++ ++ default: ++ on = ansi_highlight_red(); ++ break; ++ } ++ + printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_normal()); + } + +@@ -2399,18 +2415,19 @@ static int unit_find_paths( + return r; + } + +-static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) { ++static int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *active_state) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_free_ char *buf = NULL; +- const char *path, *state; ++ UnitActiveState state; ++ const char *path; + int r; + + assert(name); ++ assert(active_state); + + /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it + * isn't loaded. */ +- + r = sd_bus_call_method( + bus, + "org.freedesktop.systemd1", +@@ -2426,7 +2443,7 @@ static int check_one_unit(sd_bus *bus, const char *name, const char *good_states + + /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are + * considered inactive. */ +- state = "inactive"; ++ state = UNIT_INACTIVE; + + } else { + r = sd_bus_message_read(reply, "o", &path); +@@ -2444,13 +2461,15 @@ static int check_one_unit(sd_bus *bus, const char *name, const char *good_states + if (r < 0) + return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r)); + +- state = buf; ++ state = unit_active_state_from_string(buf); ++ if (state == _UNIT_ACTIVE_STATE_INVALID) { ++ log_error("Invalid unit state '%s' for: %s", buf, name); ++ return -EINVAL; ++ } + } + +- if (!quiet) +- puts(state); +- +- return nulstr_contains(good_states, state); ++ *active_state = state; ++ return 0; + } + + static int check_triggering_units( +@@ -2458,9 +2477,10 @@ static int check_triggering_units( + const char *name) { + + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +- _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL; ++ _cleanup_free_ char *path = NULL, *n = NULL, *load_state = NULL; + _cleanup_strv_free_ char **triggered_by = NULL; + bool print_warning_label = true; ++ UnitActiveState active_state; + char **i; + int r; + +@@ -2479,11 +2499,11 @@ static int check_triggering_units( + "org.freedesktop.systemd1.Unit", + "LoadState", + &error, +- &state); ++ &load_state); + if (r < 0) + return log_error_errno(r, "Failed to get load state of %s: %s", n, bus_error_message(&error, r)); + +- if (streq(state, "masked")) ++ if (streq(load_state, "masked")) + return 0; + + r = sd_bus_get_property_strv( +@@ -2498,11 +2518,11 @@ static int check_triggering_units( + return log_error_errno(r, "Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r)); + + STRV_FOREACH(i, triggered_by) { +- r = check_one_unit(bus, *i, "active\0reloading\0", true); ++ r = get_state_one_unit(bus, *i, &active_state); + if (r < 0) +- return log_error_errno(r, "Failed to check unit: %m"); ++ return r; + +- if (r == 0) ++ if (!IN_SET(active_state, UNIT_ACTIVE, UNIT_RELOADING)) + continue; + + if (print_warning_label) { +@@ -3163,11 +3183,12 @@ static int start_special(int argc, char *argv[], void *userdata) { + return start_unit(argc, argv, userdata); + } + +-static int check_unit_generic(int code, const char *good_states, char **args) { ++static int check_unit_generic(int code, const UnitActiveState good_states[], int nb_states, char **args) { + _cleanup_strv_free_ char **names = NULL; ++ UnitActiveState active_state; + sd_bus *bus; + char **name; +- int r; ++ int r, i; + bool found = false; + + r = acquire_bus(BUS_MANAGER, &bus); +@@ -3179,13 +3200,16 @@ static int check_unit_generic(int code, const char *good_states, char **args) { + return log_error_errno(r, "Failed to expand names: %m"); + + STRV_FOREACH(name, names) { +- int state; ++ r = get_state_one_unit(bus, *name, &active_state); ++ if (r < 0) ++ return r; ++ ++ if (!arg_quiet) ++ puts(unit_active_state_to_string(active_state)); + +- state = check_one_unit(bus, *name, good_states, arg_quiet); +- if (state < 0) +- return state; +- if (state > 0) +- found = true; ++ for (i = 0; i < nb_states; ++i) ++ if (good_states[i] == active_state) ++ found = true; + } + + /* use the given return code for the case that we won't find +@@ -3194,12 +3218,14 @@ static int check_unit_generic(int code, const char *good_states, char **args) { + } + + static int check_unit_active(int argc, char *argv[], void *userdata) { ++ const UnitActiveState states[] = { UNIT_ACTIVE, UNIT_RELOADING }; + /* According to LSB: 3, "program is not running" */ +- return check_unit_generic(3, "active\0reloading\0", strv_skip(argv, 1)); ++ return check_unit_generic(3, states, ELEMENTSOF(states), strv_skip(argv, 1)); + } + + static int check_unit_failed(int argc, char *argv[], void *userdata) { +- return check_unit_generic(1, "failed\0", strv_skip(argv, 1)); ++ const UnitActiveState states[] = { UNIT_FAILED }; ++ return check_unit_generic(1, states, ELEMENTSOF(states), strv_skip(argv, 1)); + } + + static int kill_unit(int argc, char *argv[], void *userdata) { +-- +2.17.1 +