Merge pull request #32389 from keszybz/bin-sbin-merge

Try PATH without sbin even if compiled with split-bin=true
This commit is contained in:
Luca Boccassi
2024-04-22 13:07:48 +02:00
committed by GitHub
6 changed files with 86 additions and 50 deletions
+29 -1
View File
@@ -696,7 +696,7 @@ int find_executable_full(
* binary. */
p = getenv("PATH");
if (!p)
p = DEFAULT_PATH;
p = default_PATH();
if (exec_search_path) {
STRV_FOREACH(element, exec_search_path) {
@@ -1453,3 +1453,31 @@ int path_glob_can_match(const char *pattern, const char *prefix, char **ret) {
*ret = NULL;
return false;
}
const char* default_PATH(void) {
#if HAVE_SPLIT_BIN
static int split = -1;
int r;
/* Check whether /usr/sbin is not a symlink and return the appropriate $PATH.
* On error fall back to the safe value with both directories as configured… */
if (split < 0)
STRV_FOREACH_PAIR(bin, sbin, STRV_MAKE("/usr/bin", "/usr/sbin",
"/usr/local/bin", "/usr/local/sbin")) {
r = inode_same(*bin, *sbin, AT_NO_AUTOMOUNT);
if (r > 0 || r == -ENOENT)
continue;
if (r < 0)
log_debug_errno(r, "Failed to compare \"%s\" and \"%s\", using compat $PATH: %m",
*bin, *sbin);
split = true;
break;
}
if (split < 0)
split = false;
if (split)
return DEFAULT_PATH_WITH_SBIN;
#endif
return DEFAULT_PATH_WITHOUT_SBIN;
}
+16 -17
View File
@@ -11,27 +11,26 @@
#include "strv.h"
#include "time-util.h"
#define PATH_SPLIT_SBIN_BIN(x) x "sbin:" x "bin"
#define PATH_SPLIT_SBIN_BIN_NULSTR(x) x "sbin\0" x "bin\0"
#define PATH_SPLIT_BIN(x) x "sbin:" x "bin"
#define PATH_SPLIT_BIN_NULSTR(x) x "sbin\0" x "bin\0"
#define PATH_NORMAL_SBIN_BIN(x) x "bin"
#define PATH_NORMAL_SBIN_BIN_NULSTR(x) x "bin\0"
#define PATH_MERGED_BIN(x) x "bin"
#define PATH_MERGED_BIN_NULSTR(x) x "bin\0"
#if HAVE_SPLIT_BIN
# define PATH_SBIN_BIN(x) PATH_SPLIT_SBIN_BIN(x)
# define PATH_SBIN_BIN_NULSTR(x) PATH_SPLIT_SBIN_BIN_NULSTR(x)
#define DEFAULT_PATH_WITH_SBIN PATH_SPLIT_BIN("/usr/local/") ":" PATH_SPLIT_BIN("/usr/")
#define DEFAULT_PATH_WITHOUT_SBIN PATH_MERGED_BIN("/usr/local/") ":" PATH_MERGED_BIN("/usr/")
#define DEFAULT_PATH_COMPAT PATH_SPLIT_BIN("/usr/local/") ":" PATH_SPLIT_BIN("/usr/") ":" PATH_SPLIT_BIN("/")
const char* default_PATH(void);
static inline const char* default_user_PATH(void) {
#ifdef DEFAULT_USER_PATH
return DEFAULT_USER_PATH;
#else
# define PATH_SBIN_BIN(x) PATH_NORMAL_SBIN_BIN(x)
# define PATH_SBIN_BIN_NULSTR(x) PATH_NORMAL_SBIN_BIN_NULSTR(x)
#endif
#define DEFAULT_PATH PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/")
#define DEFAULT_PATH_NULSTR PATH_SBIN_BIN_NULSTR("/usr/local/") PATH_SBIN_BIN_NULSTR("/usr/")
#define DEFAULT_PATH_COMPAT PATH_SPLIT_SBIN_BIN("/usr/local/") ":" PATH_SPLIT_SBIN_BIN("/usr/") ":" PATH_SPLIT_SBIN_BIN("/")
#ifndef DEFAULT_USER_PATH
# define DEFAULT_USER_PATH DEFAULT_PATH
return default_PATH();
#endif
}
static inline bool is_path(const char *p) {
if (!p) /* A NULL pointer is definitely not a path */
+10 -6
View File
@@ -658,8 +658,6 @@ static char** sanitize_environment(char **l) {
}
int manager_default_environment(Manager *m) {
int r;
assert(m);
m->transient_environment = strv_free(m->transient_environment);
@@ -670,8 +668,11 @@ int manager_default_environment(Manager *m) {
*
* The initial passed environment is untouched to keep /proc/self/environ valid; it is used
* for tagging the init process inside containers. */
m->transient_environment = strv_new("PATH=" DEFAULT_PATH);
if (!m->transient_environment)
char *path = strjoin("PATH=", default_PATH());
if (!path)
return log_oom();
if (strv_consume(&m->transient_environment, path) < 0)
return log_oom();
/* Import locale variables LC_*= from configuration */
@@ -684,8 +685,11 @@ int manager_default_environment(Manager *m) {
if (!m->transient_environment)
return log_oom();
r = strv_env_replace_strdup(&m->transient_environment, "PATH=" DEFAULT_USER_PATH);
if (r < 0)
char *path = strjoin("PATH=", default_user_PATH());
if (!path)
return log_oom();
if (strv_env_replace_consume(&m->transient_environment, path) < 0)
return log_oom();
/* Envvars set for our 'manager' class session are private and should not be propagated
+25 -19
View File
@@ -443,7 +443,7 @@ _public_ int sd_path_lookup(uint64_t type, const char *suffix, char **path) {
}
static int search_from_environment(
char ***list,
char ***ret,
const char *env_home,
const char *home_suffix,
const char *env_search,
@@ -455,7 +455,7 @@ static int search_from_environment(
char *h = NULL;
int r;
assert(list);
assert(ret);
if (env_search) {
e = secure_getenv(env_search);
@@ -465,7 +465,7 @@ static int search_from_environment(
return -ENOMEM;
if (env_search_sufficient) {
*list = TAKE_PTR(l);
*ret = TAKE_PTR(l);
return 0;
}
}
@@ -506,7 +506,7 @@ static int search_from_environment(
return -ENOMEM;
}
*list = TAKE_PTR(l);
*ret = TAKE_PTR(l);
return 0;
}
@@ -516,15 +516,15 @@ static int search_from_environment(
# define ARRAY_SBIN_BIN(x) x "bin"
#endif
static int get_search(uint64_t type, char ***list) {
static int get_search(uint64_t type, char ***ret) {
int r;
assert(list);
assert(ret);
switch (type) {
case SD_PATH_SEARCH_BINARIES:
return search_from_environment(list,
return search_from_environment(ret,
NULL,
".local/bin",
"PATH",
@@ -534,7 +534,7 @@ static int get_search(uint64_t type, char ***list) {
NULL);
case SD_PATH_SEARCH_LIBRARY_PRIVATE:
return search_from_environment(list,
return search_from_environment(ret,
NULL,
".local/lib",
NULL,
@@ -544,7 +544,7 @@ static int get_search(uint64_t type, char ***list) {
NULL);
case SD_PATH_SEARCH_LIBRARY_ARCH:
return search_from_environment(list,
return search_from_environment(ret,
NULL,
".local/lib/" LIB_ARCH_TUPLE,
"LD_LIBRARY_PATH",
@@ -553,7 +553,7 @@ static int get_search(uint64_t type, char ***list) {
NULL);
case SD_PATH_SEARCH_SHARED:
return search_from_environment(list,
return search_from_environment(ret,
"XDG_DATA_HOME",
".local/share",
"XDG_DATA_DIRS",
@@ -563,7 +563,7 @@ static int get_search(uint64_t type, char ***list) {
NULL);
case SD_PATH_SEARCH_CONFIGURATION_FACTORY:
return search_from_environment(list,
return search_from_environment(ret,
NULL,
NULL,
NULL,
@@ -573,7 +573,7 @@ static int get_search(uint64_t type, char ***list) {
NULL);
case SD_PATH_SEARCH_STATE_FACTORY:
return search_from_environment(list,
return search_from_environment(ret,
NULL,
NULL,
NULL,
@@ -583,7 +583,7 @@ static int get_search(uint64_t type, char ***list) {
NULL);
case SD_PATH_SEARCH_CONFIGURATION:
return search_from_environment(list,
return search_from_environment(ret,
"XDG_CONFIG_HOME",
".config",
"XDG_CONFIG_DIRS",
@@ -591,8 +591,14 @@ static int get_search(uint64_t type, char ***list) {
"/etc",
NULL);
case SD_PATH_SEARCH_BINARIES_DEFAULT:
return strv_from_nulstr(list, DEFAULT_PATH_NULSTR);
case SD_PATH_SEARCH_BINARIES_DEFAULT: {
char **t = strv_split(default_PATH(), ":");
if (!t)
return -ENOMEM;
*ret = t;
return 0;
}
case SD_PATH_SYSTEMD_SEARCH_SYSTEM_UNIT:
case SD_PATH_SYSTEMD_SEARCH_USER_UNIT: {
@@ -604,7 +610,7 @@ static int get_search(uint64_t type, char ***list) {
if (r < 0)
return r;
*list = TAKE_PTR(lp.search_path);
*ret = TAKE_PTR(lp.search_path);
return 0;
}
@@ -618,7 +624,7 @@ static int get_search(uint64_t type, char ***list) {
if (!t)
return -ENOMEM;
*list = t;
*ret = t;
return 0;
}
@@ -631,12 +637,12 @@ static int get_search(uint64_t type, char ***list) {
if (!t)
return -ENOMEM;
*list = t;
*ret = t;
return 0;
}
case SD_PATH_SYSTEMD_SEARCH_NETWORK:
return strv_from_nulstr(list, NETWORK_DIRS_NULSTR);
return strv_from_nulstr(ret, NETWORK_DIRS_NULSTR);
}
+4 -5
View File
@@ -331,7 +331,7 @@ TEST(environment_gathering) {
assert_se(chmod(name3, 0755) == 0);
/* When booting in containers or without initrd there might not be any PATH in the environment and if
* there is no PATH /bin/sh built-in PATH may leak and override systemd's DEFAULT_PATH which is not
* there is no PATH /bin/sh built-in PATH may leak and override systemd's default path which is not
* good. Force our own PATH in environment, to prevent expansion of sh built-in $PATH */
old = getenv("PATH");
r = setenv("PATH", "no-sh-built-in-path", 1);
@@ -351,10 +351,9 @@ TEST(environment_gathering) {
ASSERT_STREQ(strv_env_get(env, "C"), "001");
ASSERT_STREQ(strv_env_get(env, "PATH"), "no-sh-built-in-path:/no/such/file");
/* now retest with "default" path passed in, as created by
* manager_default_environment */
/* Now retest with some "default" path passed. */
env = strv_free(env);
env = strv_new("PATH=" DEFAULT_PATH);
env = strv_new("PATH=" DEFAULT_PATH_WITHOUT_SBIN);
assert_se(env);
r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL, env, EXEC_DIR_PARALLEL | EXEC_DIR_IGNORE_ERRORS);
@@ -366,7 +365,7 @@ TEST(environment_gathering) {
ASSERT_STREQ(strv_env_get(env, "A"), "22:23:24");
ASSERT_STREQ(strv_env_get(env, "B"), "12");
ASSERT_STREQ(strv_env_get(env, "C"), "001");
ASSERT_STREQ(strv_env_get(env, "PATH"), DEFAULT_PATH ":/no/such/file");
ASSERT_STREQ(strv_env_get(env, "PATH"), DEFAULT_PATH_WITHOUT_SBIN ":/no/such/file");
/* reset environ PATH */
assert_se(set_unset_env("PATH", old, true) == 0);
+2 -2
View File
@@ -18,8 +18,8 @@
#include "tmpfile-util.h"
TEST(print_paths) {
log_info("DEFAULT_PATH=%s", DEFAULT_PATH);
log_info("DEFAULT_USER_PATH=%s", DEFAULT_USER_PATH);
log_info("default system PATH: %s", default_PATH());
log_info("default user PATH: %s", default_user_PATH());
}
TEST(path) {