OSDN Git Service

selinux: allow kernfs symlinks to inherit parent directory context
authorChristian Göttsche <cgzones@googlemail.com>
Tue, 28 Jan 2020 19:16:48 +0000 (20:16 +0100)
committerPaul Moore <paul@paul-moore.com>
Mon, 10 Feb 2020 15:49:01 +0000 (10:49 -0500)
Currently symlinks on kernel filesystems, like sysfs, are labeled on
creation with the parent filesystem root sid.

Allow symlinks to inherit the parent directory context, so fine-grained
kernfs labeling can be applied to symlinks too and checking contexts
doesn't complain about them.

For backward-compatibility this behavior is contained in a new policy
capability: genfs_seclabel_symlinks

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: Paul Moore <paul@paul-moore.com>
security/selinux/hooks.c
security/selinux/include/security.h
security/selinux/ss/services.c

index d776226..7c37cdb 100644 (file)
@@ -1478,7 +1478,9 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
                /* Default to the fs superblock SID. */
                sid = sbsec->sid;
 
-               if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
+               if ((sbsec->flags & SE_SBGENFS) &&
+                    (!S_ISLNK(inode->i_mode) ||
+                     selinux_policycap_genfs_seclabel_symlinks())) {
                        /* We must have a dentry to determine the label on
                         * procfs inodes */
                        if (opt_dentry) {
index f3a6210..d6036c0 100644 (file)
@@ -79,6 +79,7 @@ enum {
        POLICYDB_CAPABILITY_ALWAYSNETWORK,
        POLICYDB_CAPABILITY_CGROUPSECLABEL,
        POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION,
+       POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS,
        __POLICYDB_CAPABILITY_MAX
 };
 #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
@@ -213,6 +214,13 @@ static inline bool selinux_policycap_nnp_nosuid_transition(void)
        return state->policycap[POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION];
 }
 
+static inline bool selinux_policycap_genfs_seclabel_symlinks(void)
+{
+       struct selinux_state *state = &selinux_state;
+
+       return state->policycap[POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS];
+}
+
 int security_mls_enabled(struct selinux_state *state);
 int security_load_policy(struct selinux_state *state,
                         void *data, size_t len);
index 922b5e4..e310f8e 100644 (file)
@@ -72,7 +72,8 @@ const char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = {
        "extended_socket_class",
        "always_check_network",
        "cgroup_seclabel",
-       "nnp_nosuid_transition"
+       "nnp_nosuid_transition",
+       "genfs_seclabel_symlinks"
 };
 
 static struct selinux_ss selinux_ss;