mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	selinux: parse contexts for mount options early
Commit b8b87fd954 ("selinux: Fix selinux_sb_mnt_opts_compat()")
started to parse mount options into SIDs in selinux_add_opt() if policy
has already been loaded. Since it's extremely unlikely that anyone would
depend on the ability to set SELinux contexts on fs_context before
loading the policy and then mounting that context after simplify the
logic by always parsing the options early.
Note that the multi-step mounting is only possible with the new
fscontext mount API and wasn't possible before its introduction.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
			
			
This commit is contained in:
		
							parent
							
								
									0e326df069
								
							
						
					
					
						commit
						70f4169ab4
					
				
					 1 changed files with 53 additions and 149 deletions
				
			
		| 
						 | 
					@ -340,7 +340,6 @@ static void inode_free_security(struct inode *inode)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct selinux_mnt_opts {
 | 
					struct selinux_mnt_opts {
 | 
				
			||||||
	const char *fscontext, *context, *rootcontext, *defcontext;
 | 
					 | 
				
			||||||
	u32 fscontext_sid;
 | 
						u32 fscontext_sid;
 | 
				
			||||||
	u32 context_sid;
 | 
						u32 context_sid;
 | 
				
			||||||
	u32 rootcontext_sid;
 | 
						u32 rootcontext_sid;
 | 
				
			||||||
| 
						 | 
					@ -349,12 +348,7 @@ struct selinux_mnt_opts {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void selinux_free_mnt_opts(void *mnt_opts)
 | 
					static void selinux_free_mnt_opts(void *mnt_opts)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct selinux_mnt_opts *opts = mnt_opts;
 | 
						kfree(mnt_opts);
 | 
				
			||||||
	kfree(opts->fscontext);
 | 
					 | 
				
			||||||
	kfree(opts->context);
 | 
					 | 
				
			||||||
	kfree(opts->rootcontext);
 | 
					 | 
				
			||||||
	kfree(opts->defcontext);
 | 
					 | 
				
			||||||
	kfree(opts);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
| 
						 | 
					@ -601,17 +595,6 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int parse_sid(struct super_block *sb, const char *s, u32 *sid)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int rc = security_context_str_to_sid(&selinux_state, s,
 | 
					 | 
				
			||||||
					     sid, GFP_KERNEL);
 | 
					 | 
				
			||||||
	if (rc)
 | 
					 | 
				
			||||||
		pr_warn("SELinux: security_context_str_to_sid"
 | 
					 | 
				
			||||||
		       "(%s) failed for (dev %s, type %s) errno=%d\n",
 | 
					 | 
				
			||||||
		       s, sb ? sb->s_id : "?", sb ? sb->s_type->name : "?", rc);
 | 
					 | 
				
			||||||
	return rc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Allow filesystems with binary mount data to explicitly set mount point
 | 
					 * Allow filesystems with binary mount data to explicitly set mount point
 | 
				
			||||||
 * labeling information.
 | 
					 * labeling information.
 | 
				
			||||||
| 
						 | 
					@ -674,49 +657,29 @@ static int selinux_set_mnt_opts(struct super_block *sb,
 | 
				
			||||||
	 * than once with different security options.
 | 
						 * than once with different security options.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (opts) {
 | 
						if (opts) {
 | 
				
			||||||
		if (opts->fscontext) {
 | 
							if (opts->fscontext_sid) {
 | 
				
			||||||
			if (opts->fscontext_sid == SECSID_NULL) {
 | 
								fscontext_sid = opts->fscontext_sid;
 | 
				
			||||||
				rc = parse_sid(sb, opts->fscontext, &fscontext_sid);
 | 
					 | 
				
			||||||
				if (rc)
 | 
					 | 
				
			||||||
					goto out;
 | 
					 | 
				
			||||||
			} else
 | 
					 | 
				
			||||||
				fscontext_sid = opts->fscontext_sid;
 | 
					 | 
				
			||||||
			if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
 | 
								if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
 | 
				
			||||||
					fscontext_sid))
 | 
										fscontext_sid))
 | 
				
			||||||
				goto out_double_mount;
 | 
									goto out_double_mount;
 | 
				
			||||||
			sbsec->flags |= FSCONTEXT_MNT;
 | 
								sbsec->flags |= FSCONTEXT_MNT;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (opts->context) {
 | 
							if (opts->context_sid) {
 | 
				
			||||||
			if (opts->context_sid == SECSID_NULL) {
 | 
								context_sid = opts->context_sid;
 | 
				
			||||||
				rc = parse_sid(sb, opts->context, &context_sid);
 | 
					 | 
				
			||||||
				if (rc)
 | 
					 | 
				
			||||||
					goto out;
 | 
					 | 
				
			||||||
			} else
 | 
					 | 
				
			||||||
				context_sid = opts->context_sid;
 | 
					 | 
				
			||||||
			if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
 | 
								if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
 | 
				
			||||||
					context_sid))
 | 
										context_sid))
 | 
				
			||||||
				goto out_double_mount;
 | 
									goto out_double_mount;
 | 
				
			||||||
			sbsec->flags |= CONTEXT_MNT;
 | 
								sbsec->flags |= CONTEXT_MNT;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (opts->rootcontext) {
 | 
							if (opts->rootcontext_sid) {
 | 
				
			||||||
			if (opts->rootcontext_sid == SECSID_NULL) {
 | 
								rootcontext_sid = opts->rootcontext_sid;
 | 
				
			||||||
				rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid);
 | 
					 | 
				
			||||||
				if (rc)
 | 
					 | 
				
			||||||
					goto out;
 | 
					 | 
				
			||||||
			} else
 | 
					 | 
				
			||||||
				rootcontext_sid = opts->rootcontext_sid;
 | 
					 | 
				
			||||||
			if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
 | 
								if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
 | 
				
			||||||
					rootcontext_sid))
 | 
										rootcontext_sid))
 | 
				
			||||||
				goto out_double_mount;
 | 
									goto out_double_mount;
 | 
				
			||||||
			sbsec->flags |= ROOTCONTEXT_MNT;
 | 
								sbsec->flags |= ROOTCONTEXT_MNT;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (opts->defcontext) {
 | 
							if (opts->defcontext_sid) {
 | 
				
			||||||
			if (opts->defcontext_sid == SECSID_NULL) {
 | 
								defcontext_sid = opts->defcontext_sid;
 | 
				
			||||||
				rc = parse_sid(sb, opts->defcontext, &defcontext_sid);
 | 
					 | 
				
			||||||
				if (rc)
 | 
					 | 
				
			||||||
					goto out;
 | 
					 | 
				
			||||||
			} else
 | 
					 | 
				
			||||||
				defcontext_sid = opts->defcontext_sid;
 | 
					 | 
				
			||||||
			if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
 | 
								if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
 | 
				
			||||||
					defcontext_sid))
 | 
										defcontext_sid))
 | 
				
			||||||
				goto out_double_mount;
 | 
									goto out_double_mount;
 | 
				
			||||||
| 
						 | 
					@ -986,6 +949,8 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct selinux_mnt_opts *opts = *mnt_opts;
 | 
						struct selinux_mnt_opts *opts = *mnt_opts;
 | 
				
			||||||
	bool is_alloc_opts = false;
 | 
						bool is_alloc_opts = false;
 | 
				
			||||||
 | 
						u32 *dst_sid;
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (token == Opt_seclabel)
 | 
						if (token == Opt_seclabel)
 | 
				
			||||||
		/* eaten and completely ignored */
 | 
							/* eaten and completely ignored */
 | 
				
			||||||
| 
						 | 
					@ -993,6 +958,11 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
 | 
				
			||||||
	if (!s)
 | 
						if (!s)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!selinux_initialized(&selinux_state)) {
 | 
				
			||||||
 | 
							pr_warn("SELinux: Unable to set superblock options before the security server is initialized\n");
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!opts) {
 | 
						if (!opts) {
 | 
				
			||||||
		opts = kzalloc(sizeof(*opts), GFP_KERNEL);
 | 
							opts = kzalloc(sizeof(*opts), GFP_KERNEL);
 | 
				
			||||||
		if (!opts)
 | 
							if (!opts)
 | 
				
			||||||
| 
						 | 
					@ -1003,36 +973,34 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (token) {
 | 
						switch (token) {
 | 
				
			||||||
	case Opt_context:
 | 
						case Opt_context:
 | 
				
			||||||
		if (opts->context || opts->defcontext)
 | 
							if (opts->context_sid || opts->defcontext_sid)
 | 
				
			||||||
			goto err;
 | 
								goto err;
 | 
				
			||||||
		opts->context = s;
 | 
							dst_sid = &opts->context_sid;
 | 
				
			||||||
		if (selinux_initialized(&selinux_state))
 | 
					 | 
				
			||||||
			parse_sid(NULL, s, &opts->context_sid);
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case Opt_fscontext:
 | 
						case Opt_fscontext:
 | 
				
			||||||
		if (opts->fscontext)
 | 
							if (opts->fscontext_sid)
 | 
				
			||||||
			goto err;
 | 
								goto err;
 | 
				
			||||||
		opts->fscontext = s;
 | 
							dst_sid = &opts->fscontext_sid;
 | 
				
			||||||
		if (selinux_initialized(&selinux_state))
 | 
					 | 
				
			||||||
			parse_sid(NULL, s, &opts->fscontext_sid);
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case Opt_rootcontext:
 | 
						case Opt_rootcontext:
 | 
				
			||||||
		if (opts->rootcontext)
 | 
							if (opts->rootcontext_sid)
 | 
				
			||||||
			goto err;
 | 
								goto err;
 | 
				
			||||||
		opts->rootcontext = s;
 | 
							dst_sid = &opts->rootcontext_sid;
 | 
				
			||||||
		if (selinux_initialized(&selinux_state))
 | 
					 | 
				
			||||||
			parse_sid(NULL, s, &opts->rootcontext_sid);
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case Opt_defcontext:
 | 
						case Opt_defcontext:
 | 
				
			||||||
		if (opts->context || opts->defcontext)
 | 
							if (opts->context_sid || opts->defcontext_sid)
 | 
				
			||||||
			goto err;
 | 
								goto err;
 | 
				
			||||||
		opts->defcontext = s;
 | 
							dst_sid = &opts->defcontext_sid;
 | 
				
			||||||
		if (selinux_initialized(&selinux_state))
 | 
					 | 
				
			||||||
			parse_sid(NULL, s, &opts->defcontext_sid);
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							WARN_ON(1);
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						rc = security_context_str_to_sid(&selinux_state, s, dst_sid, GFP_KERNEL);
 | 
				
			||||||
	return 0;
 | 
						if (rc)
 | 
				
			||||||
 | 
							pr_warn("SELinux: security_context_str_to_sid (%s) failed with errno=%d\n",
 | 
				
			||||||
 | 
								s, rc);
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err:
 | 
					err:
 | 
				
			||||||
	if (is_alloc_opts) {
 | 
						if (is_alloc_opts) {
 | 
				
			||||||
| 
						 | 
					@ -2681,37 +2649,27 @@ static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts)
 | 
				
			||||||
	if (!opts)
 | 
						if (!opts)
 | 
				
			||||||
		return (sbsec->flags & SE_MNTMASK) ? 1 : 0;
 | 
							return (sbsec->flags & SE_MNTMASK) ? 1 : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (opts->fscontext) {
 | 
						if (opts->fscontext_sid) {
 | 
				
			||||||
		if (opts->fscontext_sid == SECSID_NULL)
 | 
							if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
 | 
				
			||||||
			return 1;
 | 
								       opts->fscontext_sid))
 | 
				
			||||||
		else if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
 | 
					 | 
				
			||||||
				       opts->fscontext_sid))
 | 
					 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (opts->context) {
 | 
						if (opts->context_sid) {
 | 
				
			||||||
		if (opts->context_sid == SECSID_NULL)
 | 
							if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
 | 
				
			||||||
			return 1;
 | 
								       opts->context_sid))
 | 
				
			||||||
		else if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
 | 
					 | 
				
			||||||
				       opts->context_sid))
 | 
					 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (opts->rootcontext) {
 | 
						if (opts->rootcontext_sid) {
 | 
				
			||||||
		if (opts->rootcontext_sid == SECSID_NULL)
 | 
							struct inode_security_struct *root_isec;
 | 
				
			||||||
			return 1;
 | 
					 | 
				
			||||||
		else {
 | 
					 | 
				
			||||||
			struct inode_security_struct *root_isec;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			root_isec = backing_inode_security(sb->s_root);
 | 
							root_isec = backing_inode_security(sb->s_root);
 | 
				
			||||||
			if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
 | 
							if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
 | 
				
			||||||
				       opts->rootcontext_sid))
 | 
								       opts->rootcontext_sid))
 | 
				
			||||||
				return 1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (opts->defcontext) {
 | 
					 | 
				
			||||||
		if (opts->defcontext_sid == SECSID_NULL)
 | 
					 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
		else if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
 | 
						}
 | 
				
			||||||
				       opts->defcontext_sid))
 | 
						if (opts->defcontext_sid) {
 | 
				
			||||||
 | 
							if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
 | 
				
			||||||
 | 
								       opts->defcontext_sid))
 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -2721,7 +2679,6 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct selinux_mnt_opts *opts = mnt_opts;
 | 
						struct selinux_mnt_opts *opts = mnt_opts;
 | 
				
			||||||
	struct superblock_security_struct *sbsec = selinux_superblock(sb);
 | 
						struct superblock_security_struct *sbsec = selinux_superblock(sb);
 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(sbsec->flags & SE_SBINITIALIZED))
 | 
						if (!(sbsec->flags & SE_SBINITIALIZED))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					@ -2729,47 +2686,24 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
 | 
				
			||||||
	if (!opts)
 | 
						if (!opts)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (opts->fscontext) {
 | 
						if (opts->fscontext_sid) {
 | 
				
			||||||
		if (opts->fscontext_sid == SECSID_NULL) {
 | 
					 | 
				
			||||||
			rc = parse_sid(sb, opts->fscontext,
 | 
					 | 
				
			||||||
				       &opts->fscontext_sid);
 | 
					 | 
				
			||||||
			if (rc)
 | 
					 | 
				
			||||||
				return rc;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
 | 
							if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
 | 
				
			||||||
			       opts->fscontext_sid))
 | 
								       opts->fscontext_sid))
 | 
				
			||||||
			goto out_bad_option;
 | 
								goto out_bad_option;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (opts->context) {
 | 
						if (opts->context_sid) {
 | 
				
			||||||
		if (opts->context_sid == SECSID_NULL) {
 | 
					 | 
				
			||||||
			rc = parse_sid(sb, opts->context, &opts->context_sid);
 | 
					 | 
				
			||||||
			if (rc)
 | 
					 | 
				
			||||||
				return rc;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
 | 
							if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
 | 
				
			||||||
			       opts->context_sid))
 | 
								       opts->context_sid))
 | 
				
			||||||
			goto out_bad_option;
 | 
								goto out_bad_option;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (opts->rootcontext) {
 | 
						if (opts->rootcontext_sid) {
 | 
				
			||||||
		struct inode_security_struct *root_isec;
 | 
							struct inode_security_struct *root_isec;
 | 
				
			||||||
		root_isec = backing_inode_security(sb->s_root);
 | 
							root_isec = backing_inode_security(sb->s_root);
 | 
				
			||||||
		if (opts->rootcontext_sid == SECSID_NULL) {
 | 
					 | 
				
			||||||
			rc = parse_sid(sb, opts->rootcontext,
 | 
					 | 
				
			||||||
				       &opts->rootcontext_sid);
 | 
					 | 
				
			||||||
			if (rc)
 | 
					 | 
				
			||||||
				return rc;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
 | 
							if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
 | 
				
			||||||
			       opts->rootcontext_sid))
 | 
								       opts->rootcontext_sid))
 | 
				
			||||||
			goto out_bad_option;
 | 
								goto out_bad_option;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (opts->defcontext) {
 | 
						if (opts->defcontext_sid) {
 | 
				
			||||||
		if (opts->defcontext_sid == SECSID_NULL) {
 | 
					 | 
				
			||||||
			rc = parse_sid(sb, opts->defcontext,
 | 
					 | 
				
			||||||
				       &opts->defcontext_sid);
 | 
					 | 
				
			||||||
			if (rc)
 | 
					 | 
				
			||||||
				return rc;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
 | 
							if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
 | 
				
			||||||
			       opts->defcontext_sid))
 | 
								       opts->defcontext_sid))
 | 
				
			||||||
			goto out_bad_option;
 | 
								goto out_bad_option;
 | 
				
			||||||
| 
						 | 
					@ -2838,42 +2772,12 @@ static int selinux_fs_context_dup(struct fs_context *fc,
 | 
				
			||||||
				  struct fs_context *src_fc)
 | 
									  struct fs_context *src_fc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct selinux_mnt_opts *src = src_fc->security;
 | 
						const struct selinux_mnt_opts *src = src_fc->security;
 | 
				
			||||||
	struct selinux_mnt_opts *opts;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!src)
 | 
						if (!src)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fc->security = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL);
 | 
						fc->security = kmemdup(src, sizeof(*src), GFP_KERNEL);
 | 
				
			||||||
	if (!fc->security)
 | 
						return fc->security ? 0 : -ENOMEM;
 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	opts = fc->security;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (src->fscontext) {
 | 
					 | 
				
			||||||
		opts->fscontext = kstrdup(src->fscontext, GFP_KERNEL);
 | 
					 | 
				
			||||||
		if (!opts->fscontext)
 | 
					 | 
				
			||||||
			return -ENOMEM;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (src->context) {
 | 
					 | 
				
			||||||
		opts->context = kstrdup(src->context, GFP_KERNEL);
 | 
					 | 
				
			||||||
		if (!opts->context)
 | 
					 | 
				
			||||||
			return -ENOMEM;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (src->rootcontext) {
 | 
					 | 
				
			||||||
		opts->rootcontext = kstrdup(src->rootcontext, GFP_KERNEL);
 | 
					 | 
				
			||||||
		if (!opts->rootcontext)
 | 
					 | 
				
			||||||
			return -ENOMEM;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (src->defcontext) {
 | 
					 | 
				
			||||||
		opts->defcontext = kstrdup(src->defcontext, GFP_KERNEL);
 | 
					 | 
				
			||||||
		if (!opts->defcontext)
 | 
					 | 
				
			||||||
			return -ENOMEM;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	opts->fscontext_sid = src->fscontext_sid;
 | 
					 | 
				
			||||||
	opts->context_sid = src->context_sid;
 | 
					 | 
				
			||||||
	opts->rootcontext_sid = src->rootcontext_sid;
 | 
					 | 
				
			||||||
	opts->defcontext_sid = src->defcontext_sid;
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct fs_parameter_spec selinux_fs_parameters[] = {
 | 
					static const struct fs_parameter_spec selinux_fs_parameters[] = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue