]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
util-lib: get_current_dir_name() can return errors other than ENOMEM
authorLennart Poettering <lennart@poettering.net>
Thu, 22 Oct 2015 17:28:31 +0000 (19:28 +0200)
committerLennart Poettering <lennart@poettering.net>
Sat, 24 Oct 2015 21:03:49 +0000 (23:03 +0200)
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.

src/basic/path-util.c
src/basic/path-util.h
src/basic/selinux-util.c
src/firstboot/firstboot.c
src/journal/coredumpctl.c
src/machine/machinectl.c
src/nspawn/nspawn.c
src/shared/path-lookup.c
src/sysusers/sysusers.c
src/tmpfiles/tmpfiles.c

index 9aeb8c23fd8bc269dc6dee6be64bd8e299083ba3..96705cc9d8d2fa46ff036777ba1228c8c8539cbc 100644 (file)
@@ -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;
index 03e1ac5d60941f57df278ba17fa5ff243a120e5d..c37c131bff153ca746599a5c5d65d63f9c3026c6 100644 (file)
 #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);
 
index 747e6f4dbb3af7772ce043fdafb6835fad41322a..7a7dc90e3c471a12092614ce84a321bffc8dd40b 100644 (file)
@@ -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;
 }
index 82ebb9178861203d10ac18d3e1721bbe63501bdb..cee05de7a1dfd9b1081be797d990e56aaed62c94 100644 (file)
@@ -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:
index dde56008c152a00549146f96995f6eff65f53e11..97a721c114062593ae69d12524536b137ed3e348 100644 (file)
@@ -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:
index d7e0395690c8d3df64fcf20fe44d92c0d21e0e48..f44f4edc0a732fe13a29b53c8c292e88ea883b53 100644 (file)
@@ -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;
 }
index 99e24cf4ff76e10cb6d35238661dda27a79c1d1d..056b4ce5f308a65d888f67b6ba87d456651e9cf9 100644 (file)
@@ -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);
index 34eec959ef910191120915394ea31b91fb5c2250..897dc9065f93245400194bee01b9ce818024433b 100644 (file)
@@ -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
 }
 
index ba09727080ac8cd0e873c67888af6c378dff4e6c..e594053ee835ba8ea25063e28702de68c71bd84a 100644 (file)
@@ -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;
index 09b6ca5c2c1559bb3e78a910af70d1cdf46703b2..693a3da2f4de457f25f688df911ce1edf8f0d7b6 100644 (file)
@@ -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;