summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-10-22 19:28:31 +0200
committerLennart Poettering <lennart@poettering.net>2015-10-24 23:03:49 +0200
commit0f4743651081b5367ab06f238827ddfd4da74e74 (patch)
tree43b072e7eb30af4c4c80fa451768ecd8eb14a1d9 /src/basic
parent85eca92e2061043d733991b386d8dc10fad0fc30 (diff)
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.
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/path-util.c60
-rw-r--r--src/basic/path-util.h6
-rw-r--r--src/basic/selinux-util.c94
3 files changed, 91 insertions, 69 deletions
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index 9aeb8c23fd..96705cc9d8 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -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;
+
+ c = strjoin(cwd, "/", p, NULL);
+ }
+ if (!c)
+ return -ENOMEM;
- return strjoin(cwd, "/", p, NULL);
+ *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;
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
index 03e1ac5d60..c37c131bff 100644
--- a/src/basic/path-util.h
+++ b/src/basic/path-util.h
@@ -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);
diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c
index 747e6f4dbb..7a7dc90e3c 100644
--- a/src/basic/selinux-util.c
+++ b/src/basic/selinux-util.c
@@ -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;
}