selinux: revert SECINITSID_INIT support
authorPaul Moore <paul@paul-moore.com>
Tue, 8 Aug 2023 02:57:22 +0000 (22:57 -0400)
committerPaul Moore <paul@paul-moore.com>
Wed, 9 Aug 2023 14:51:13 +0000 (10:51 -0400)
This commit reverts 5b0eea835d4e ("selinux: introduce an initial SID
for early boot processes") as it was found to cause problems on
distros with old SELinux userspace tools/libraries, specifically
Ubuntu 16.04.

Hopefully we will be able to re-add this functionality at a later
date, but let's revert this for now to help ensure a stable and
backwards compatible SELinux tree.

Link: https://lore.kernel.org/selinux/87edkseqf8.fsf@mail.lhotse
Acked-by: Ondrej Mosnacek <omosnace@redhat.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
security/selinux/hooks.c
security/selinux/include/initial_sid_to_string.h
security/selinux/include/policycap.h
security/selinux/include/policycap_names.h
security/selinux/include/security.h
security/selinux/ss/policydb.c

index cf787ea..7138083 100644 (file)
@@ -2313,19 +2313,6 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
        new_tsec->keycreate_sid = 0;
        new_tsec->sockcreate_sid = 0;
 
-       /*
-        * Before policy is loaded, label any task outside kernel space
-        * as SECINITSID_INIT, so that any userspace tasks surviving from
-        * early boot end up with a label different from SECINITSID_KERNEL
-        * (if the policy chooses to set SECINITSID_INIT != SECINITSID_KERNEL).
-        */
-       if (!selinux_initialized()) {
-               new_tsec->sid = SECINITSID_INIT;
-               /* also clear the exec_sid just in case */
-               new_tsec->exec_sid = 0;
-               return 0;
-       }
-
        if (old_tsec->exec_sid) {
                new_tsec->sid = old_tsec->exec_sid;
                /* Reset exec SID on execve. */
@@ -4542,21 +4529,6 @@ static int sock_has_perm(struct sock *sk, u32 perms)
        if (sksec->sid == SECINITSID_KERNEL)
                return 0;
 
-       /*
-        * Before POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT, sockets that
-        * inherited the kernel context from early boot used to be skipped
-        * here, so preserve that behavior unless the capability is set.
-        *
-        * By setting the capability the policy signals that it is ready
-        * for this quirk to be fixed. Note that sockets created by a kernel
-        * thread or a usermode helper executed without a transition will
-        * still be skipped in this check regardless of the policycap
-        * setting.
-        */
-       if (!selinux_policycap_userspace_initial_context() &&
-           sksec->sid == SECINITSID_INIT)
-               return 0;
-
        ad_net_init_from_sk(&ad, &net, sk);
 
        return avc_has_perm(current_sid(), sksec->sid, sksec->sclass, perms,
index 5e5f099..ecc6e74 100644 (file)
@@ -10,7 +10,7 @@ static const char *const initial_sid_to_string[] = {
        NULL,
        "file",
        NULL,
-       "init",
+       NULL,
        "any_socket",
        "port",
        "netif",
index c7373e6..f35d345 100644 (file)
@@ -12,7 +12,6 @@ enum {
        POLICYDB_CAP_NNP_NOSUID_TRANSITION,
        POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS,
        POLICYDB_CAP_IOCTL_SKIP_CLOEXEC,
-       POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT,
        __POLICYDB_CAP_MAX
 };
 #define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1)
index 28e4c9e..49bbe12 100644 (file)
@@ -14,7 +14,6 @@ const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = {
        "nnp_nosuid_transition",
        "genfs_seclabel_symlinks",
        "ioctl_skip_cloexec",
-       "userspace_initial_context",
 };
 
 #endif /* _SELINUX_POLICYCAP_NAMES_H_ */
index 074d439..a9de89a 100644 (file)
@@ -189,12 +189,6 @@ static inline bool selinux_policycap_ioctl_skip_cloexec(void)
                selinux_state.policycap[POLICYDB_CAP_IOCTL_SKIP_CLOEXEC]);
 }
 
-static inline bool selinux_policycap_userspace_initial_context(void)
-{
-       return READ_ONCE(
-               selinux_state.policycap[POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT]);
-}
-
 struct selinux_policy_convert_data;
 
 struct selinux_load_state {
index bb850b6..cd44b13 100644 (file)
@@ -864,8 +864,6 @@ void policydb_destroy(struct policydb *p)
 int policydb_load_isids(struct policydb *p, struct sidtab *s)
 {
        struct ocontext *head, *c;
-       bool isid_init_supported = ebitmap_get_bit(&p->policycaps,
-                                                  POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT);
        int rc;
 
        rc = sidtab_init(s);
@@ -889,13 +887,6 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
                if (!name)
                        continue;
 
-               /*
-                * Also ignore SECINITSID_INIT if the policy doesn't declare
-                * support for it
-                */
-               if (sid == SECINITSID_INIT && !isid_init_supported)
-                       continue;
-
                rc = sidtab_set_initial(s, sid, &c->context[0]);
                if (rc) {
                        pr_err("SELinux:  unable to load initial SID %s.\n",
@@ -903,24 +894,6 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
                        sidtab_destroy(s);
                        return rc;
                }
-
-               /*
-                * If the policy doesn't support the "userspace_initial_context"
-                * capability, set SECINITSID_INIT to the same context as
-                * SECINITSID_KERNEL. This ensures the same behavior as before
-                * the reintroduction of SECINITSID_INIT, where all tasks
-                * started before policy load would initially get the context
-                * corresponding to SECINITSID_KERNEL.
-                */
-               if (sid == SECINITSID_KERNEL && !isid_init_supported) {
-                       rc = sidtab_set_initial(s, SECINITSID_INIT, &c->context[0]);
-                       if (rc) {
-                               pr_err("SELinux:  unable to load initial SID %s.\n",
-                                      name);
-                               sidtab_destroy(s);
-                               return rc;
-                       }
-               }
        }
        return 0;
 }