]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
selinux: accept the fact that getxyzcon() can return success and NULL
authorLennart Poettering <lennart@poettering.net>
Wed, 7 Dec 2022 14:20:15 +0000 (15:20 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 7 Dec 2022 14:25:37 +0000 (15:25 +0100)
Inspired by #25664: let's check explicitly for NULL everywhere we do one
of those getXYZcon() calls.

We usually turn this into EOPNOTSUPP, as when selinux is off (which is
supposed to be the only case this can happen according to selinux docs)
we otherwise return EOPNOTSUPP in that case.

Note that in most cases we have an explicit mac_selinux_use() call
beforehand, hence this should mostly not be triggerable codepaths.

src/core/selinux-access.c
src/shared/selinux-util.c

index e05ebdc631d533536160b3ac6af0bb8fd57cb1dd..62181a6309b936929ed92b68fed07dbec62183c8 100644 (file)
@@ -229,9 +229,7 @@ int mac_selinux_access_check_internal(
         } else {
                 /* If no unit context is known, use our own */
                 if (getcon_raw(&fcon) < 0) {
-                        r = -errno;
-
-                        log_warning_errno(r, "SELinux getcon_raw() failed%s (perm=%s): %m",
+                        log_warning_errno(errno, "SELinux getcon_raw() failed%s (perm=%s): %m",
                                           enforce ? "" : ", ignoring",
                                           permission);
                         if (!enforce)
@@ -239,6 +237,12 @@ int mac_selinux_access_check_internal(
 
                         return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get current context: %m");
                 }
+                if (!fcon) {
+                        if (!enforce)
+                                return 0;
+
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "We appear not to have any SELinux context: %m");
+                }
 
                 acon = fcon;
                 tclass = "system";
index f7d8353b49c182ab8d28439f75e7b2403dc520a9..e240cdc2c32702a616189fc58b8a18eb81ef7959 100644 (file)
@@ -277,7 +277,7 @@ static int selinux_fix_fd(
                         return 0;
 
                 /* If the old label is identical to the new one, suppress any kind of error */
-                if (getfilecon_raw(FORMAT_PROC_FD_PATH(fd), &oldcon) >= 0 && streq(fcon, oldcon))
+                if (getfilecon_raw(FORMAT_PROC_FD_PATH(fd), &oldcon) >= 0 && streq_ptr(fcon, oldcon))
                         return 0;
 
                 return log_enforcing_errno(r, "Unable to fix SELinux security context of %s: %m", label_path);
@@ -381,9 +381,13 @@ int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
 
         if (getcon_raw(&mycon) < 0)
                 return -errno;
+        if (!mycon)
+                return -EOPNOTSUPP;
 
         if (getfilecon_raw(exe, &fcon) < 0)
                 return -errno;
+        if (!fcon)
+                return -EOPNOTSUPP;
 
         sclass = string_to_security_class("process");
         if (sclass == 0)
@@ -395,14 +399,21 @@ int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
 #endif
 }
 
-int mac_selinux_get_our_label(char **label) {
-#if HAVE_SELINUX
-        assert(label);
+int mac_selinux_get_our_label(char **ret) {
+        assert(ret);
 
+#if HAVE_SELINUX
         if (!mac_selinux_use())
                 return -EOPNOTSUPP;
 
-        return RET_NERRNO(getcon_raw(label));
+        _cleanup_freecon_ char *con = NULL;
+        if (getcon_raw(&con) < 0)
+                return -errno;
+        if (!con)
+                return -EOPNOTSUPP;
+
+        *ret = TAKE_PTR(con);
+        return 0;
 #else
         return -EOPNOTSUPP;
 #endif
@@ -424,13 +435,20 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *
 
         if (getcon_raw(&mycon) < 0)
                 return -errno;
+        if (!mycon)
+                return -EOPNOTSUPP;
 
         if (getpeercon_raw(socket_fd, &peercon) < 0)
                 return -errno;
+        if (!peercon)
+                return -EOPNOTSUPP;
 
-        if (!exec_label) /* If there is no context set for next exec let's use context of target executable */
+        if (!exec_label) /* If there is no context set for next exec let's use context of target executable */
                 if (getfilecon_raw(exe, &fcon) < 0)
                         return -errno;
+                if (!fcon)
+                        return -EOPNOTSUPP;
+        }
 
         bcon = context_new(mycon);
         if (!bcon)