summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/dbus-manager.c42
-rw-r--r--src/shared/env-util.c15
-rw-r--r--src/shared/env-util.h2
3 files changed, 36 insertions, 23 deletions
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 7071196238..de23369397 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -1542,7 +1542,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
m->exit_code = MANAGER_SWITCH_ROOT;
} else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetEnvironment")) {
- char **l = NULL, **e = NULL;
+ _cleanup_strv_free_ char **l = NULL;
+ char **e = NULL;
SELINUX_ACCESS_CHECK(connection, message, "reboot");
@@ -1551,9 +1552,10 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
goto oom;
if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
+ if (!strv_env_is_valid(l))
+ return bus_send_error_reply(connection, message, NULL, -EINVAL);
e = strv_env_merge(2, m->environment, l);
- strv_free(l);
if (!e)
goto oom;
@@ -1567,7 +1569,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
m->environment = e;
} else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetEnvironment")) {
- char **l = NULL, **e = NULL;
+ _cleanup_strv_free_ char **l = NULL;
+ char **e = NULL;
SELINUX_ACCESS_CHECK(connection, message, "reboot");
@@ -1576,10 +1579,10 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
goto oom;
if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
+ if (!strv_env_name_or_assignment_is_valid(l))
+ return bus_send_error_reply(connection, message, NULL, -EINVAL);
e = strv_env_delete(m->environment, 1, l);
- strv_free(l);
-
if (!e)
goto oom;
@@ -1593,7 +1596,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
m->environment = e;
} else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetAndSetEnvironment")) {
- char **l_set = NULL, **l_unset = NULL, **e = NULL, **f = NULL;
+ _cleanup_strv_free_ char **l_set = NULL, **l_unset = NULL, **e = NULL;
+ char **f = NULL;
DBusMessageIter iter;
SELINUX_ACCESS_CHECK(connection, message, "reboot");
@@ -1606,33 +1610,25 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
goto oom;
if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
+ if (!strv_env_name_or_assignment_is_valid(l_unset))
+ return bus_send_error_reply(connection, message, NULL, -EINVAL);
- if (!dbus_message_iter_next(&iter)) {
- strv_free(l_unset);
+ if (!dbus_message_iter_next(&iter))
return bus_send_error_reply(connection, message, NULL, -EINVAL);
- }
r = bus_parse_strv_iter(&iter, &l_set);
- if (r < 0) {
- strv_free(l_unset);
- if (r == -ENOMEM)
- goto oom;
-
+ if (r == -ENOMEM)
+ goto oom;
+ if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
- }
+ if (!strv_env_is_valid(l_set))
+ return bus_send_error_reply(connection, message, NULL, -EINVAL);
e = strv_env_delete(m->environment, 1, l_unset);
- strv_free(l_unset);
-
- if (!e) {
- strv_free(l_set);
+ if (!e)
goto oom;
- }
f = strv_env_merge(2, e, l_set);
- strv_free(l_set);
- strv_free(e);
-
if (!f)
goto oom;
diff --git a/src/shared/env-util.c b/src/shared/env-util.c
index 7a213a77c0..9a833d22e4 100644
--- a/src/shared/env-util.c
+++ b/src/shared/env-util.c
@@ -135,6 +135,21 @@ bool strv_env_is_valid(char **e) {
return true;
}
+bool strv_env_name_or_assignment_is_valid(char **l) {
+ char **p, **q;
+
+ STRV_FOREACH(p, l) {
+ if (!env_assignment_is_valid(*p) && !env_name_is_valid(*p))
+ return false;
+
+ STRV_FOREACH(q, p + 1)
+ if (streq(*p, *q))
+ return false;
+ }
+
+ return true;
+}
+
static int env_append(char **r, char ***k, char **a) {
assert(r);
assert(k);
diff --git a/src/shared/env-util.h b/src/shared/env-util.h
index 93bf596ca8..9449576b5c 100644
--- a/src/shared/env-util.h
+++ b/src/shared/env-util.h
@@ -31,6 +31,8 @@ bool env_assignment_is_valid(const char *e);
bool strv_env_is_valid(char **e);
char **strv_env_clean(char **l);
+bool strv_env_name_or_assignment_is_valid(char **l);
+
char **strv_env_merge(unsigned n_lists, ...);
char **strv_env_delete(char **x, unsigned n_lists, ...); /* New copy */