From 93547f2812f457312a8b13b640e42f4f671ef244 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 19 Jan 2021 17:11:55 +0000 Subject: [PATCH] env-util: refactor parsing helper for SYSTEMD_SYSEXT_HIERARCHIES out of sysext --- src/basic/env-util.c | 42 ++++++++++++++++++++++++++++++++++++++ src/basic/env-util.h | 4 ++++ src/sysext/sysext.c | 48 ++++++-------------------------------------- 3 files changed, 52 insertions(+), 42 deletions(-) diff --git a/src/basic/env-util.c b/src/basic/env-util.c index 137d6b1f3cb..df24cb935d3 100644 --- a/src/basic/env-util.c +++ b/src/basic/env-util.c @@ -12,6 +12,7 @@ #include "extract-word.h" #include "macro.h" #include "parse-util.h" +#include "path-util.h" #include "process-util.h" #include "stdio-util.h" #include "string-util.h" @@ -787,3 +788,44 @@ int setenv_systemd_exec_pid(bool update_only) { return 1; } + +int getenv_path_list(const char *name, char ***ret_paths) { + _cleanup_strv_free_ char **l = NULL; + const char *e; + char **p; + int r; + + assert(name); + assert(ret_paths); + + *ret_paths = NULL; + + e = secure_getenv(name); + if (!e) + return 0; + + r = strv_split_full(&l, e, ":", EXTRACT_DONT_COALESCE_SEPARATORS); + if (r < 0) + return log_debug_errno(r, "Failed to parse $%s: %m", name); + + STRV_FOREACH(p, l) { + if (!path_is_absolute(*p)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "Path '%s' is not absolute, refusing.", *p); + + if (!path_is_normalized(*p)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "Path '%s' is not normalized, refusing.", *p); + + if (path_equal(*p, "/")) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "Path '%s' is the root fs, refusing.", *p); + } + + if (strv_isempty(l)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "No paths specified, refusing."); + + *ret_paths = TAKE_PTR(l); + return 0; +} diff --git a/src/basic/env-util.h b/src/basic/env-util.h index 79307a4a5fe..7ba8488af7f 100644 --- a/src/basic/env-util.h +++ b/src/basic/env-util.h @@ -59,3 +59,7 @@ int getenv_bool_secure(const char *p); int set_unset_env(const char *name, const char *value, bool overwrite); int setenv_systemd_exec_pid(bool update_only); + +/* Parses and does sanity checks on an environment variable containing + * PATH-like colon-separated absolute paths */ +int getenv_path_list(const char *name, char ***ret_paths); diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index 141c64993e8..cd824887bf7 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -8,6 +8,7 @@ #include "capability-util.h" #include "discover-image.h" #include "dissect-image.h" +#include "env-util.h" #include "escape.h" #include "fd-util.h" #include "fileio.h" @@ -954,46 +955,6 @@ static int parse_argv(int argc, char *argv[]) { return 1; } -static int parse_env(void) { - _cleanup_strv_free_ char **l = NULL; - const char *e; - char **p; - int r; - - e = secure_getenv("SYSTEMD_SYSEXT_HIERARCHIES"); - if (!e) - return 0; - - /* For debugging purposes it might make sense to do this for other hierarchies than /usr/ and - * /opt/, but let's make that a hacker/debugging feature, i.e. env var instead of cmdline - * switch. */ - - r = strv_split_full(&l, e, ":", EXTRACT_DONT_COALESCE_SEPARATORS); - if (r < 0) - return log_error_errno(r, "Failed to parse $SYSTEMD_SYSEXT_HIERARCHIES: %m"); - - STRV_FOREACH(p, l) { - if (!path_is_absolute(*p)) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Hierarchy path '%s' is not absolute, refusing.", *p); - - if (!path_is_normalized(*p)) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Hierarchy path '%s' is not normalized, refusing.", *p); - - if (path_equal(*p, "/")) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Hierarchy path '%s' is the root fs, refusing.", *p); - } - - if (strv_isempty(l)) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "No hierarchies specified, refusing."); - - strv_free_and_replace(arg_hierarchies, l); - return 0; -} - static int sysext_main(int argc, char *argv[]) { static const Verb verbs[] = { @@ -1018,9 +979,12 @@ static int run(int argc, char *argv[]) { if (r <= 0) return r; - r = parse_env(); + /* For debugging purposes it might make sense to do this for other hierarchies than /usr/ and + * /opt/, but let's make that a hacker/debugging feature, i.e. env var instead of cmdline + * switch. */ + r = getenv_path_list("SYSTEMD_SYSEXT_HIERARCHIES", &arg_hierarchies); if (r < 0) - return r; + return log_error_errno(r, "Failed to parse $SYSTEMD_SYSEXT_HIERARCHIES environment variable: %m"); if (!arg_hierarchies) { arg_hierarchies = strv_new("/usr", "/opt"); -- 2.47.3