Re: [PATCH] selinux: consider filesystem subtype in policies

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm seeking feedback if this general approach is acceptable. I am willing to clean the patch up further (if any comments) and provide testing results if there is acceptance on the approach.

Thanks,
Avati

On Apr 16, 2013, at 11:29 AM, Anand Avati <avati@xxxxxxxxxx> wrote:

> Not considering filesystem has the following limitation. Support
> for SELinux in FUSE is dependent on the particular userspace
> filesystem, which is identified by the subtype. For e.g, GlusterFS,
> a FUSE based filesystem supports SELinux (by mounting and processing
> FUSE requests in different threads, avoiding the mount time
> deadlock), whereas other FUSE based filesystems (identified by a
> different subtype) have the mount time deadlock.
> 
> By considering the subtype of the filesytem in the SELinux policies,
> allows us to specify a filesystem subtype, in the following way:
> 
> fs_use_xattr fuse.glusterfs gen_context(system_u:object_r:fs_t,s0);
> 
> This way not all FUSE filesystems are put in the same bucket and
> subjected to the limitations of the other subtypes.
> 
> Signed-off-by: Anand Avati <avati@xxxxxxxxxx>
> ---
> security/selinux/hooks.c            | 46 ++++++++++++++++++++-----------------
> security/selinux/include/security.h |  2 +-
> security/selinux/ss/services.c      |  7 +++++-
> 3 files changed, 32 insertions(+), 23 deletions(-)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 84b59171..437ecdc 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -93,6 +93,10 @@
> #include "audit.h"
> #include "avc_ss.h"
> 
> +#define SB_TYPE_FMT "%s%s%s"
> +#define SB_SUBTYPE(sb) (sb->s_subtype && sb->s_subtype[0])
> +#define SB_TYPE_ARGS(sb) sb->s_type->name, SB_SUBTYPE(sb) ? "." : "", SB_SUBTYPE(sb) ? sb->s_subtype : ""
> +
> #define NUM_SEL_MNT_OPTS 5
> 
> extern struct security_operations *security_ops;
> @@ -366,8 +370,8 @@ static int sb_finish_set_opts(struct super_block *sb)
> 		   the first boot of the SELinux kernel before we have
> 		   assigned xattr values to the filesystem. */
> 		if (!root_inode->i_op->getxattr) {
> -			printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
> -			       "xattr support\n", sb->s_id, sb->s_type->name);
> +			printk(KERN_WARNING "SELinux: (dev %s, type "SB_TYPE_FMT") has no "
> +			       "xattr support\n", sb->s_id, SB_TYPE_ARGS(sb));
> 			rc = -EOPNOTSUPP;
> 			goto out;
> 		}
> @@ -375,12 +379,12 @@ static int sb_finish_set_opts(struct super_block *sb)
> 		if (rc < 0 && rc != -ENODATA) {
> 			if (rc == -EOPNOTSUPP)
> 				printk(KERN_WARNING "SELinux: (dev %s, type "
> -				       "%s) has no security xattr handler\n",
> -				       sb->s_id, sb->s_type->name);
> +				       SB_TYPE_FMT") has no security xattr handler\n",
> +				       sb->s_id, SB_TYPE_ARGS(sb));
> 			else
> 				printk(KERN_WARNING "SELinux: (dev %s, type "
> -				       "%s) getxattr errno %d\n", sb->s_id,
> -				       sb->s_type->name, -rc);
> +				       SB_TYPE_FMT") getxattr errno %d\n", sb->s_id,
> +				       SB_TYPE_ARGS(sb), -rc);
> 			goto out;
> 		}
> 	}
> @@ -388,11 +392,11 @@ static int sb_finish_set_opts(struct super_block *sb)
> 	sbsec->flags |= (SE_SBINITIALIZED | SE_SBLABELSUPP);
> 
> 	if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
> -		printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
> -		       sb->s_id, sb->s_type->name);
> +		printk(KERN_ERR "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), unknown behavior\n",
> +		       sb->s_id, SB_TYPE_ARGS(sb));
> 	else
> -		printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n",
> -		       sb->s_id, sb->s_type->name,
> +		printk(KERN_DEBUG "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), %s\n",
> +		       sb->s_id, SB_TYPE_ARGS(sb),
> 		       labeling_behaviors[sbsec->behavior-1]);
> 
> 	if (sbsec->behavior == SECURITY_FS_USE_GENFS ||
> @@ -556,7 +560,6 @@ static int selinux_set_mnt_opts(struct super_block *sb,
> 	const struct cred *cred = current_cred();
> 	int rc = 0, i;
> 	struct superblock_security_struct *sbsec = sb->s_security;
> -	const char *name = sb->s_type->name;
> 	struct inode *inode = sbsec->sb->s_root->d_inode;
> 	struct inode_security_struct *root_isec = inode->i_security;
> 	u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
> @@ -609,8 +612,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
> 					     strlen(mount_options[i]), &sid);
> 		if (rc) {
> 			printk(KERN_WARNING "SELinux: security_context_to_sid"
> -			       "(%s) failed for (dev %s, type %s) errno=%d\n",
> -			       mount_options[i], sb->s_id, name, rc);
> +			       "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
> +			       mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
> 			goto out;
> 		}
> 		switch (flags[i]) {
> @@ -670,10 +673,10 @@ static int selinux_set_mnt_opts(struct super_block *sb,
> 		sbsec->flags |= SE_SBPROC;
> 
> 	/* Determine the labeling behavior to use for this filesystem type. */
> -	rc = security_fs_use((sbsec->flags & SE_SBPROC) ? "proc" : sb->s_type->name, &sbsec->behavior, &sbsec->sid);
> +	rc = security_fs_use((sbsec->flags & SE_SBPROC) ? "proc" : sb->s_type->name, SB_SUBTYPE(sb) ? sb->s_subtype : NULL, &sbsec->behavior, &sbsec->sid);
> 	if (rc) {
> -		printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n",
> -		       __func__, sb->s_type->name, rc);
> +		printk(KERN_WARNING "%s: security_fs_use("SB_TYPE_FMT") returned %d\n",
> +		       __func__, SB_TYPE_ARGS(sb), rc);
> 		goto out;
> 	}
> 
> @@ -746,7 +749,8 @@ out:
> out_double_mount:
> 	rc = -EINVAL;
> 	printk(KERN_WARNING "SELinux: mount invalid.  Same superblock, different "
> -	       "security settings for (dev %s, type %s)\n", sb->s_id, name);
> +	       "security settings for (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
> +	       SB_TYPE_ARGS(sb));
> 	goto out;
> }
> 
> @@ -2375,8 +2379,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
> 		rc = security_context_to_sid(mount_options[i], len, &sid);
> 		if (rc) {
> 			printk(KERN_WARNING "SELinux: security_context_to_sid"
> -			       "(%s) failed for (dev %s, type %s) errno=%d\n",
> -			       mount_options[i], sb->s_id, sb->s_type->name, rc);
> +			       "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
> +			       mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
> 			goto out_free_opts;
> 		}
> 		rc = -EINVAL;
> @@ -2414,8 +2418,8 @@ out_free_secdata:
> 	return rc;
> out_bad_option:
> 	printk(KERN_WARNING "SELinux: unable to change security options "
> -	       "during remount (dev %s, type=%s)\n", sb->s_id,
> -	       sb->s_type->name);
> +	       "during remount (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
> +	       SB_TYPE_ARGS(sb));
> 	goto out_free_opts;
> }
> 
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 6d38851..5ec1877 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -170,7 +170,7 @@ int security_get_allow_unknown(void);
> #define SECURITY_FS_USE_NONE		5 /* no labeling support */
> #define SECURITY_FS_USE_MNTPOINT	6 /* use mountpoint labeling */
> 
> -int security_fs_use(const char *fstype, unsigned int *behavior,
> +int security_fs_use(const char *fstype, const char *subtype, unsigned int *behavior,
> 	u32 *sid);
> 
> int security_genfs_sid(const char *fstype, char *name, u16 sclass,
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index b4feecc..3c6cbba 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -2329,17 +2329,22 @@ out:
>  */
> int security_fs_use(
> 	const char *fstype,
> +	const char *subtype,
> 	unsigned int *behavior,
> 	u32 *sid)
> {
> 	int rc = 0;
> 	struct ocontext *c;
> +	char type[32];
> 
> 	read_lock(&policy_rwlock);
> 
> 	c = policydb.ocontexts[OCON_FSUSE];
> +	snprintf(type, 32, "%s%s%s", fstype,
> +		 (subtype ? "." : ""), (subtype ? subtype : ""));
> +	type[31] = 0;
> 	while (c) {
> -		if (strcmp(fstype, c->u.name) == 0)
> +		if (strcmp(type, c->u.name) == 0)
> 			break;
> 		c = c->next;
> 	}
> -- 
> 1.7.12.1
> 
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
> the words "unsubscribe selinux" without quotes as the message.



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.




[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux