chiark / gitweb /
clang: fix numerous little issues found with clang-analyzer
[elogind.git] / src / util.c
index 2279efac493f1d9c7ebda2f6f60eb3217cc77a5b..a2def28730c935f0f3bc684ac37b5ebe8410d11e 100644 (file)
 #include "log.h"
 #include "strv.h"
 
-#if HAVE_SELINUX
+#ifdef HAVE_SELINUX
 #include <selinux/selinux.h>
 #include <selinux/label.h>
 
 static struct selabel_handle *label_hnd = NULL;
 
-static inline int use_selinux(void) {
+static inline bool use_selinux(void) {
         static int use_selinux_ind = -1;
 
-        if (use_selinux_ind == -1)
-                use_selinux_ind = (is_selinux_enabled() == 1);
+        if (use_selinux_ind < 0)
+                use_selinux_ind = is_selinux_enabled() > 0;
 
         return use_selinux_ind;
 }
@@ -84,6 +84,8 @@ static int label_get_file_label_from_path(
         r = getfilecon(path, &dir_con);
         if (r >= 0) {
                 r = -1;
+                errno = EINVAL;
+
                 if ((sclass = string_to_security_class(class)) != 0)
                         r = security_compute_create((security_context_t) label, dir_con, sclass, fcon);
         }
@@ -99,13 +101,16 @@ static int label_get_file_label_from_path(
 int label_init(void) {
         int r = 0;
 
-#if HAVE_SELINUX
-        if (use_selinux()) {
-                label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
-                if (!label_hnd) {
-                        log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, "Failed to initialize SELinux context: %m");
-                        r = (security_getenforce() == 1) ? -errno : 0;
-                }
+#ifdef HAVE_SELINUX
+
+        if (!use_selinux())
+                return 0;
+
+        label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
+        if (!label_hnd) {
+                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
+                         "Failed to initialize SELinux context: %m");
+                r = (security_getenforce() == 1) ? -errno : 0;
         }
 #endif
 
@@ -114,47 +119,54 @@ int label_init(void) {
 
 int label_fix(const char *path) {
         int r = 0;
-#if HAVE_SELINUX
+
+#ifdef HAVE_SELINUX
         struct stat st;
         security_context_t fcon;
-        if (use_selinux()) {
-                r = lstat(path, &st);
 
-                if (r == 0) {
-                        r = selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode);
+        if (!use_selinux() || !label_hnd)
+                return 0;
 
-                        if (r == 0) {
-                                r = setfilecon(path, fcon);
-                                freecon(fcon);
-                        }
-                }
-                if (r < 0) {
-                        log_error("Unable to fix label of %s: %m", path);
-                        r = (security_getenforce() == 1) ? -errno : 0;
+        r = lstat(path, &st);
+        if (r == 0) {
+                r = selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode);
+
+                if (r == 0) {
+                        r = setfilecon(path, fcon);
+                        freecon(fcon);
                 }
         }
+        if (r < 0) {
+                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
+                         "Unable to fix label of %s: %m", path);
+                r = (security_getenforce() == 1) ? -errno : 0;
+        }
 #endif
+
         return r;
 }
 
 void label_finish(void) {
 
-#if HAVE_SELINUX
-        if (use_selinux())
+#ifdef HAVE_SELINUX
+        if (use_selinux() && label_hnd)
                 selabel_close(label_hnd);
 #endif
-
 }
 
-int label_get_socket_label_from_exe(
-        const char *exe,
-        char **label) {
+int label_get_socket_label_from_exe(const char *exe, char **label) {
+
         int r = 0;
 
-#if HAVE_SELINUX
+#ifdef HAVE_SELINUX
         security_context_t mycon = NULL, fcon = NULL;
         security_class_t sclass;
 
+        if (!use_selinux()) {
+                *label = NULL;
+                return 0;
+        }
+
         r = getcon(&mycon);
         if (r < 0)
                 goto fail;
@@ -169,7 +181,7 @@ int label_get_socket_label_from_exe(
                 log_debug("SELinux Socket context for %s will be set to %s", exe, *label);
 
 fail:
-        if (r< 0 && security_getenforce() == 1)
+        if (r < 0 && security_getenforce() == 1)
                 r = -errno;
 
         freecon(mycon);
@@ -182,21 +194,23 @@ fail:
 int label_fifofile_set(const char *label, const char *path) {
         int r = 0;
 
-#if HAVE_SELINUX
+#ifdef HAVE_SELINUX
         security_context_t filecon = NULL;
-        if (use_selinux() && label) {
-                if (((r = label_get_file_label_from_path(label, path, "fifo_file", &filecon)) == 0)) {
-                        if ((r = setfscreatecon(filecon)) < 0) {
-                                log_error("Failed to set SELinux file context (%s) on %s: %m", label, path);
-                                r = -errno;
-                        }
 
-                        freecon(filecon);
+        if (!use_selinux() || !label)
+                return 0;
+
+        if (((r = label_get_file_label_from_path(label, path, "fifo_file", &filecon)) == 0)) {
+                if ((r = setfscreatecon(filecon)) < 0) {
+                        log_error("Failed to set SELinux file context (%s) on %s: %m", label, path);
+                        r = -errno;
                 }
 
-                if (r < 0  && security_getenforce() == 0)
-                        r = 0;
+                freecon(filecon);
         }
+
+        if (r < 0 && security_getenforce() == 0)
+                r = 0;
 #endif
 
         return r;
@@ -204,9 +218,14 @@ int label_fifofile_set(const char *label, const char *path) {
 
 int label_socket_set(const char *label) {
 
-#if HAVE_SELINUX
-        if (use_selinux() && setsockcreatecon((security_context_t) label) < 0) {
-                log_error("Failed to set SELinux context (%s) on socket: %m", label);
+#ifdef HAVE_SELINUX
+        if (!use_selinux())
+                return 0;
+
+        if (setsockcreatecon((security_context_t) label) < 0) {
+                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
+                         "Failed to set SELinux context (%s) on socket: %m", label);
+
                 if (security_getenforce() == 1)
                         return -errno;
         }
@@ -217,43 +236,43 @@ int label_socket_set(const char *label) {
 
 void label_file_clear(void) {
 
-#if HAVE_SELINUX
-        if (use_selinux())
-                setfscreatecon(NULL);
-#endif
+#ifdef HAVE_SELINUX
+        if (!use_selinux())
+                return;
 
-        return;
+        setfscreatecon(NULL);
+#endif
 }
 
-void label_free(const char *label) {
+void label_socket_clear(void) {
 
-#if HAVE_SELINUX
-        if (use_selinux())
-                freecon((security_context_t) label);
-#endif
+#ifdef HAVE_SELINUX
+        if (!use_selinux())
+                return;
 
-        return;
+        setsockcreatecon(NULL);
+#endif
 }
 
-void label_socket_clear(void) {
+void label_free(const char *label) {
 
-#if HAVE_SELINUX
-        if (use_selinux())
-                setsockcreatecon(NULL);
-#endif
+#ifdef HAVE_SELINUX
+        if (!use_selinux())
+                return;
 
-        return;
+        freecon((security_context_t) label);
+#endif
 }
 
 static int label_mkdir(
         const char *path,
         mode_t mode) {
 
-#if HAVE_SELINUX
+#ifdef HAVE_SELINUX
         int r;
         security_context_t fcon = NULL;
 
-        if (use_selinux()) {
+        if (use_selinux() && label_hnd) {
                 if (path[0] == '/') {
                         r = selabel_lookup_raw(label_hnd, &fcon, path, mode);
                 }
@@ -283,7 +302,7 @@ static int label_mkdir(
         r = mkdir(path, mode);
 
 finish:
-        if (use_selinux()) {
+        if (use_selinux() && label_hnd) {
                 setfscreatecon(NULL);
                 freecon(fcon);
         }
@@ -1917,6 +1936,12 @@ char *format_timespan(char *buf, size_t l, usec_t t) {
         if (t == (usec_t) -1)
                 return NULL;
 
+        if (t == 0) {
+                snprintf(p, l, "0");
+                p[l-1] = 0;
+                return p;
+        }
+
         /* The result of this function can be parsed with parse_usec */
 
         for (i = 0; i < ELEMENTSOF(table); i++) {
@@ -3060,18 +3085,18 @@ char *replace_env(const char *format, char **env) {
 
                 case VARIABLE:
                         if (*e == '}') {
-                                char *t;
+                                const char *t;
 
-                                if ((t = strv_env_get_with_length(env, word+2, e-word-2))) {
-                                        if (!(k = strappend(r, t)))
-                                                goto fail;
+                                if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
+                                        t = "";
 
-                                        free(r);
-                                        r = k;
+                                if (!(k = strappend(r, t)))
+                                        goto fail;
 
-                                        word = e+1;
-                                }
+                                free(r);
+                                r = k;
 
+                                word = e+1;
                                 state = WORD;
                         }
                         break;
@@ -3101,36 +3126,39 @@ char **replace_env_argv(char **argv, char **env) {
         STRV_FOREACH(i, argv) {
 
                 /* If $FOO appears as single word, replace it by the split up variable */
-                if ((*i)[0] == '$') {
-                        char *e = strv_env_get(env, *i+1);
+                if ((*i)[0] == '$' && (*i)[1] != '{') {
+                        char *e;
+                        char **w, **m;
+                        unsigned q;
 
-                        if (e) {
-                                char **w, **m;
-                                unsigned q;
+                        if ((e = strv_env_get(env, *i+1))) {
 
                                 if (!(m = strv_split_quoted(e))) {
                                         r[k] = NULL;
                                         strv_free(r);
                                         return NULL;
                                 }
+                        } else
+                                m = NULL;
 
-                                q = strv_length(m);
-                                l = l + q - 1;
+                        q = strv_length(m);
+                        l = l + q - 1;
 
-                                if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
-                                        r[k] = NULL;
-                                        strv_free(r);
-                                        strv_free(m);
-                                        return NULL;
-                                }
+                        if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
+                                r[k] = NULL;
+                                strv_free(r);
+                                strv_free(m);
+                                return NULL;
+                        }
 
-                                r = w;
+                        r = w;
+                        if (m) {
                                 memcpy(r + k, m, q * sizeof(char*));
                                 free(m);
-
-                                k += q;
-                                continue;
                         }
+
+                        k += q;
+                        continue;
                 }
 
                 /* If ${FOO} appears as part of a word, replace it by the variable as-is */