mirror of
https://github.com/systemd/systemd.git
synced 2025-03-14 04:58:28 +03:00
util-lib: get_current_dir_name() can return errors other than ENOMEM
get_current_dir_name() can return a variety of errors, not just ENOMEM, hence don't blindly turn its errors to ENOMEM, but return correct errors in path_make_absolute_cwd(). This trickles down into a couple of other functions, some of which receive unrelated minor fixes too with this commit.
This commit is contained in:
parent
85eca92e20
commit
0f47436510
@ -84,20 +84,25 @@ int path_get_parent(const char *path, char **_r) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **path_split_and_make_absolute(const char *p) {
|
||||
int path_split_and_make_absolute(const char *p, char ***ret) {
|
||||
char **l;
|
||||
int r;
|
||||
|
||||
assert(p);
|
||||
assert(ret);
|
||||
|
||||
l = strv_split(p, ":");
|
||||
if (!l)
|
||||
return NULL;
|
||||
|
||||
if (!path_strv_make_absolute_cwd(l)) {
|
||||
r = path_strv_make_absolute_cwd(l);
|
||||
if (r < 0) {
|
||||
strv_free(l);
|
||||
return NULL;
|
||||
return r;
|
||||
}
|
||||
|
||||
return l;
|
||||
*ret = l;
|
||||
return r;
|
||||
}
|
||||
|
||||
char *path_make_absolute(const char *p, const char *prefix) {
|
||||
@ -112,22 +117,31 @@ char *path_make_absolute(const char *p, const char *prefix) {
|
||||
return strjoin(prefix, "/", p, NULL);
|
||||
}
|
||||
|
||||
char *path_make_absolute_cwd(const char *p) {
|
||||
_cleanup_free_ char *cwd = NULL;
|
||||
int path_make_absolute_cwd(const char *p, char **ret) {
|
||||
char *c;
|
||||
|
||||
assert(p);
|
||||
assert(ret);
|
||||
|
||||
/* Similar to path_make_absolute(), but prefixes with the
|
||||
* current working directory. */
|
||||
|
||||
if (path_is_absolute(p))
|
||||
return strdup(p);
|
||||
c = strdup(p);
|
||||
else {
|
||||
_cleanup_free_ char *cwd = NULL;
|
||||
|
||||
cwd = get_current_dir_name();
|
||||
if (!cwd)
|
||||
return NULL;
|
||||
cwd = get_current_dir_name();
|
||||
if (!cwd)
|
||||
return -errno;
|
||||
|
||||
return strjoin(cwd, "/", p, NULL);
|
||||
c = strjoin(cwd, "/", p, NULL);
|
||||
}
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int path_make_relative(const char *from_dir, const char *to_path, char **_r) {
|
||||
@ -215,8 +229,9 @@ int path_make_relative(const char *from_dir, const char *to_path, char **_r) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **path_strv_make_absolute_cwd(char **l) {
|
||||
int path_strv_make_absolute_cwd(char **l) {
|
||||
char **s;
|
||||
int r;
|
||||
|
||||
/* Goes through every item in the string list and makes it
|
||||
* absolute. This works in place and won't rollback any
|
||||
@ -225,15 +240,15 @@ char **path_strv_make_absolute_cwd(char **l) {
|
||||
STRV_FOREACH(s, l) {
|
||||
char *t;
|
||||
|
||||
t = path_make_absolute_cwd(*s);
|
||||
if (!t)
|
||||
return NULL;
|
||||
r = path_make_absolute_cwd(*s, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
free(*s);
|
||||
*s = t;
|
||||
}
|
||||
|
||||
return l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **path_strv_resolve(char **l, const char *prefix) {
|
||||
@ -719,13 +734,9 @@ int find_binary(const char *name, char **ret) {
|
||||
return -errno;
|
||||
|
||||
if (ret) {
|
||||
char *rs;
|
||||
|
||||
rs = path_make_absolute_cwd(name);
|
||||
if (!rs)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = rs;
|
||||
r = path_make_absolute_cwd(name, ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -750,6 +761,9 @@ int find_binary(const char *name, char **ret) {
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (!path_is_absolute(element))
|
||||
continue;
|
||||
|
||||
j = strjoin(element, "/", name, NULL);
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
@ -36,11 +36,11 @@
|
||||
#endif
|
||||
|
||||
bool is_path(const char *p) _pure_;
|
||||
char** path_split_and_make_absolute(const char *p);
|
||||
int path_split_and_make_absolute(const char *p, char ***ret);
|
||||
int path_get_parent(const char *path, char **parent);
|
||||
bool path_is_absolute(const char *p) _pure_;
|
||||
char* path_make_absolute(const char *p, const char *prefix);
|
||||
char* path_make_absolute_cwd(const char *p);
|
||||
int path_make_absolute_cwd(const char *p, char **ret);
|
||||
int path_make_relative(const char *from_dir, const char *to_path, char **_r);
|
||||
char* path_kill_slashes(char *path);
|
||||
char* path_startswith(const char *path, const char *prefix) _pure_;
|
||||
@ -49,7 +49,7 @@ bool path_equal(const char *a, const char *b) _pure_;
|
||||
bool path_equal_or_files_same(const char *a, const char *b);
|
||||
char* path_join(const char *root, const char *path, const char *rest);
|
||||
|
||||
char** path_strv_make_absolute_cwd(char **l);
|
||||
int path_strv_make_absolute_cwd(char **l);
|
||||
char** path_strv_resolve(char **l, const char *prefix);
|
||||
char** path_strv_resolve_uniq(char **l, const char *prefix);
|
||||
|
||||
|
@ -171,15 +171,15 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
|
||||
int mac_selinux_apply(const char *path, const char *label) {
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
assert(path);
|
||||
assert(label);
|
||||
|
||||
if (!mac_selinux_use())
|
||||
return 0;
|
||||
|
||||
assert(path);
|
||||
assert(label);
|
||||
|
||||
if (setfilecon(path, (security_context_t) label) < 0) {
|
||||
log_enforcing("Failed to set SELinux security context %s on path %s: %m", label, path);
|
||||
if (security_getenforce() == 1)
|
||||
if (security_getenforce() > 0)
|
||||
return -errno;
|
||||
}
|
||||
#endif
|
||||
@ -312,10 +312,10 @@ char* mac_selinux_free(char *label) {
|
||||
}
|
||||
|
||||
int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
|
||||
int r = 0;
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
_cleanup_security_context_free_ security_context_t filecon = NULL;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
|
||||
@ -325,34 +325,33 @@ int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
|
||||
if (path_is_absolute(path))
|
||||
r = selabel_lookup_raw(label_hnd, &filecon, path, mode);
|
||||
else {
|
||||
_cleanup_free_ char *newpath;
|
||||
_cleanup_free_ char *newpath = NULL;
|
||||
|
||||
newpath = path_make_absolute_cwd(path);
|
||||
if (!newpath)
|
||||
return -ENOMEM;
|
||||
r = path_make_absolute_cwd(path, &newpath);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = selabel_lookup_raw(label_hnd, &filecon, newpath, mode);
|
||||
}
|
||||
|
||||
/* No context specified by the policy? Proceed without setting it. */
|
||||
if (r < 0 && errno == ENOENT)
|
||||
return 0;
|
||||
if (r < 0) {
|
||||
/* No context specified by the policy? Proceed without setting it. */
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
if (r < 0)
|
||||
r = -errno;
|
||||
else {
|
||||
r = setfscreatecon(filecon);
|
||||
if (r < 0) {
|
||||
log_enforcing("Failed to set SELinux security context %s for %s: %m", filecon, path);
|
||||
r = -errno;
|
||||
}
|
||||
log_enforcing("Failed to determine SELinux security context for %s: %m", path);
|
||||
} else {
|
||||
if (setfscreatecon(filecon) >= 0)
|
||||
return 0; /* Success! */
|
||||
|
||||
log_enforcing("Failed to set SELinux security context %s for %s: %m", filecon, path);
|
||||
}
|
||||
|
||||
if (r < 0 && security_getenforce() == 0)
|
||||
r = 0;
|
||||
#endif
|
||||
if (security_getenforce() > 0)
|
||||
return -errno;
|
||||
|
||||
return r;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mac_selinux_create_file_clear(void) {
|
||||
@ -405,6 +404,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
#ifdef HAVE_SELINUX
|
||||
_cleanup_security_context_free_ security_context_t fcon = NULL;
|
||||
const struct sockaddr_un *un;
|
||||
bool context_changed = false;
|
||||
char *path;
|
||||
int r;
|
||||
|
||||
@ -420,7 +420,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
goto skipped;
|
||||
|
||||
/* Filter out anonymous sockets */
|
||||
if (addrlen < sizeof(sa_family_t) + 1)
|
||||
if (addrlen < offsetof(struct sockaddr_un, sun_path) + 1)
|
||||
goto skipped;
|
||||
|
||||
/* Filter out abstract namespace sockets */
|
||||
@ -433,36 +433,44 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
if (path_is_absolute(path))
|
||||
r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK);
|
||||
else {
|
||||
_cleanup_free_ char *newpath;
|
||||
_cleanup_free_ char *newpath = NULL;
|
||||
|
||||
newpath = path_make_absolute_cwd(path);
|
||||
if (!newpath)
|
||||
return -ENOMEM;
|
||||
r = path_make_absolute_cwd(path, &newpath);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFSOCK);
|
||||
}
|
||||
|
||||
if (r == 0)
|
||||
r = setfscreatecon(fcon);
|
||||
if (r < 0) {
|
||||
/* No context specified by the policy? Proceed without setting it */
|
||||
if (errno == ENOENT)
|
||||
goto skipped;
|
||||
|
||||
if (r < 0 && errno != ENOENT) {
|
||||
log_enforcing("Failed to set SELinux security context %s for %s: %m", fcon, path);
|
||||
log_enforcing("Failed to determine SELinux security context for %s: %m", path);
|
||||
if (security_getenforce() > 0)
|
||||
return -errno;
|
||||
|
||||
if (security_getenforce() == 1) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
} else {
|
||||
if (setfscreatecon(fcon) < 0) {
|
||||
log_enforcing("Failed to set SELinux security context %s for %s: %m", fcon, path);
|
||||
if (security_getenforce() > 0)
|
||||
return -errno;
|
||||
} else
|
||||
context_changed = true;
|
||||
}
|
||||
|
||||
r = bind(fd, addr, addrlen);
|
||||
if (r < 0)
|
||||
r = -errno;
|
||||
r = bind(fd, addr, addrlen) < 0 ? -errno : 0;
|
||||
|
||||
if (context_changed)
|
||||
setfscreatecon(NULL);
|
||||
|
||||
finish:
|
||||
setfscreatecon(NULL);
|
||||
return r;
|
||||
|
||||
skipped:
|
||||
#endif
|
||||
return bind(fd, addr, addrlen) < 0 ? -errno : 0;
|
||||
if (bind(fd, addr, addrlen) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -690,16 +690,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return version();
|
||||
|
||||
case ARG_ROOT:
|
||||
free(arg_root);
|
||||
arg_root = path_make_absolute_cwd(optarg);
|
||||
if (!arg_root)
|
||||
return log_oom();
|
||||
arg_root = mfree(arg_root);
|
||||
r = path_make_absolute_cwd(optarg, &arg_root);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to make root path absolute: %m");
|
||||
|
||||
path_kill_slashes(arg_root);
|
||||
|
||||
if (path_equal(arg_root, "/"))
|
||||
arg_root = mfree(arg_root);
|
||||
|
||||
break;
|
||||
|
||||
case ARG_LOCALE:
|
||||
|
@ -84,37 +84,35 @@ static Set *new_matches(void) {
|
||||
}
|
||||
|
||||
static int add_match(Set *set, const char *match) {
|
||||
int r = -ENOMEM;
|
||||
unsigned pid;
|
||||
const char* prefix;
|
||||
char *pattern = NULL;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
char *pattern = NULL;
|
||||
const char* prefix;
|
||||
pid_t pid;
|
||||
int r;
|
||||
|
||||
if (strchr(match, '='))
|
||||
prefix = "";
|
||||
else if (strchr(match, '/')) {
|
||||
p = path_make_absolute_cwd(match);
|
||||
if (!p)
|
||||
r = path_make_absolute_cwd(match, &p);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
match = p;
|
||||
prefix = "COREDUMP_EXE=";
|
||||
}
|
||||
else if (safe_atou(match, &pid) == 0)
|
||||
} else if (parse_pid(match, &pid) >= 0)
|
||||
prefix = "COREDUMP_PID=";
|
||||
else
|
||||
prefix = "COREDUMP_COMM=";
|
||||
|
||||
pattern = strjoin(prefix, match, NULL);
|
||||
if (!pattern)
|
||||
if (!pattern) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
log_debug("Adding pattern: %s", pattern);
|
||||
r = set_consume(set, pattern);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to add pattern: %m");
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
|
@ -1092,9 +1092,10 @@ static int copy_files(int argc, char *argv[], void *userdata) {
|
||||
container_path = copy_from ? argv[2] : dest;
|
||||
|
||||
if (!path_is_absolute(host_path)) {
|
||||
abs_host_path = path_make_absolute_cwd(host_path);
|
||||
if (!abs_host_path)
|
||||
return log_oom();
|
||||
r = path_make_absolute_cwd(host_path, &abs_host_path);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to make path absolute: %m");
|
||||
|
||||
host_path = abs_host_path;
|
||||
}
|
||||
|
||||
@ -1110,10 +1111,8 @@ static int copy_files(int argc, char *argv[], void *userdata) {
|
||||
argv[1],
|
||||
copy_from ? container_path : host_path,
|
||||
copy_from ? host_path : container_path);
|
||||
if (r < 0) {
|
||||
log_error("Failed to copy: %s", bus_error_message(&error, -r));
|
||||
return r;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -278,6 +278,7 @@ static int custom_mounts_prepare(void) {
|
||||
|
||||
static int set_sanitized_path(char **b, const char *path) {
|
||||
char *p;
|
||||
int r;
|
||||
|
||||
assert(b);
|
||||
assert(path);
|
||||
@ -287,9 +288,9 @@ static int set_sanitized_path(char **b, const char *path) {
|
||||
if (errno != ENOENT)
|
||||
return -errno;
|
||||
|
||||
p = path_make_absolute_cwd(path);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
r = path_make_absolute_cwd(path, &p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
free(*b);
|
||||
|
@ -210,7 +210,7 @@ static char** user_dirs(
|
||||
if (strv_extend(&res, generator_late) < 0)
|
||||
return NULL;
|
||||
|
||||
if (!path_strv_make_absolute_cwd(res))
|
||||
if (path_strv_make_absolute_cwd(res) < 0)
|
||||
return NULL;
|
||||
|
||||
tmp = res;
|
||||
@ -244,6 +244,7 @@ int lookup_paths_init(
|
||||
|
||||
const char *e;
|
||||
bool append = false; /* Add items from SYSTEMD_UNIT_PATH before normal directories */
|
||||
int r;
|
||||
|
||||
assert(p);
|
||||
|
||||
@ -259,9 +260,9 @@ int lookup_paths_init(
|
||||
/* FIXME: empty components in other places should be
|
||||
* rejected. */
|
||||
|
||||
p->unit_path = path_split_and_make_absolute(e);
|
||||
if (!p->unit_path)
|
||||
return -ENOMEM;
|
||||
r = path_split_and_make_absolute(e, &p->unit_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else
|
||||
p->unit_path = NULL;
|
||||
|
||||
@ -269,7 +270,6 @@ int lookup_paths_init(
|
||||
/* Let's figure something out. */
|
||||
|
||||
_cleanup_strv_free_ char **unit_path;
|
||||
int r;
|
||||
|
||||
/* For the user units we include share/ in the search
|
||||
* path in order to comply with the XDG basedir spec.
|
||||
@ -342,9 +342,9 @@ int lookup_paths_init(
|
||||
|
||||
e = getenv("SYSTEMD_SYSVINIT_PATH");
|
||||
if (e) {
|
||||
p->sysvinit_path = path_split_and_make_absolute(e);
|
||||
if (!p->sysvinit_path)
|
||||
return -ENOMEM;
|
||||
r = path_split_and_make_absolute(e, &p->sysvinit_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else
|
||||
p->sysvinit_path = NULL;
|
||||
|
||||
@ -360,9 +360,9 @@ int lookup_paths_init(
|
||||
|
||||
e = getenv("SYSTEMD_SYSVRCND_PATH");
|
||||
if (e) {
|
||||
p->sysvrcnd_path = path_split_and_make_absolute(e);
|
||||
if (!p->sysvrcnd_path)
|
||||
return -ENOMEM;
|
||||
r = path_split_and_make_absolute(e, &p->sysvrcnd_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else
|
||||
p->sysvrcnd_path = NULL;
|
||||
|
||||
@ -417,9 +417,8 @@ void lookup_paths_free(LookupPaths *p) {
|
||||
p->unit_path = strv_free(p->unit_path);
|
||||
|
||||
#ifdef HAVE_SYSV_COMPAT
|
||||
strv_free(p->sysvinit_path);
|
||||
strv_free(p->sysvrcnd_path);
|
||||
p->sysvinit_path = p->sysvrcnd_path = NULL;
|
||||
p->sysvinit_path = strv_free(p->sysvinit_path);
|
||||
p->sysvrcnd_path = strv_free(p->sysvrcnd_path);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1762,7 +1762,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{}
|
||||
};
|
||||
|
||||
int c;
|
||||
int c, r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
@ -1779,10 +1779,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return version();
|
||||
|
||||
case ARG_ROOT:
|
||||
free(arg_root);
|
||||
arg_root = path_make_absolute_cwd(optarg);
|
||||
if (!arg_root)
|
||||
return log_oom();
|
||||
arg_root = mfree(arg_root);
|
||||
r = path_make_absolute_cwd(optarg, &arg_root);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to make root path absolute: %m");
|
||||
|
||||
path_kill_slashes(arg_root);
|
||||
break;
|
||||
|
@ -2101,7 +2101,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{}
|
||||
};
|
||||
|
||||
int c;
|
||||
int c, r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
@ -2144,10 +2144,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
|
||||
case ARG_ROOT:
|
||||
free(arg_root);
|
||||
arg_root = path_make_absolute_cwd(optarg);
|
||||
if (!arg_root)
|
||||
return log_oom();
|
||||
arg_root = mfree(arg_root);
|
||||
r = path_make_absolute_cwd(optarg, &arg_root);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to make root path absolute: %m");
|
||||
|
||||
path_kill_slashes(arg_root);
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user