mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	selinux: new helper - selinux_add_opt()
the guts of the loop in selinux_parse_opts_str() - takes one (already recognized) option and adds it to growing selinux_mnt_opts. Reviewed-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									84d8c4a5ef
								
							
						
					
					
						commit
						ba64186233
					
				
					 1 changed files with 53 additions and 73 deletions
				
			
		| 
						 | 
					@ -984,97 +984,77 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int selinux_add_opt(int token, const char *s, void **mnt_opts)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct selinux_mnt_opts *opts = *mnt_opts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!opts) {
 | 
				
			||||||
 | 
							opts = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!opts)
 | 
				
			||||||
 | 
								return -ENOMEM;
 | 
				
			||||||
 | 
							*mnt_opts = opts;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!s)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
						switch (token) {
 | 
				
			||||||
 | 
						case Opt_context:
 | 
				
			||||||
 | 
							if (opts->context || opts->defcontext)
 | 
				
			||||||
 | 
								goto Einval;
 | 
				
			||||||
 | 
							opts->context = s;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case Opt_fscontext:
 | 
				
			||||||
 | 
							if (opts->fscontext)
 | 
				
			||||||
 | 
								goto Einval;
 | 
				
			||||||
 | 
							opts->fscontext = s;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case Opt_rootcontext:
 | 
				
			||||||
 | 
							if (opts->rootcontext)
 | 
				
			||||||
 | 
								goto Einval;
 | 
				
			||||||
 | 
							opts->rootcontext = s;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case Opt_defcontext:
 | 
				
			||||||
 | 
							if (opts->context || opts->defcontext)
 | 
				
			||||||
 | 
								goto Einval;
 | 
				
			||||||
 | 
							opts->defcontext = s;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					Einval:
 | 
				
			||||||
 | 
						pr_warn(SEL_MOUNT_FAIL_MSG);
 | 
				
			||||||
 | 
						kfree(s);
 | 
				
			||||||
 | 
						return -EINVAL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int selinux_parse_opts_str(char *options,
 | 
					static int selinux_parse_opts_str(char *options,
 | 
				
			||||||
				  void **mnt_opts)
 | 
									  void **mnt_opts)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct selinux_mnt_opts *opts = *mnt_opts;
 | 
					 | 
				
			||||||
	char *p;
 | 
						char *p;
 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Standard string-based options. */
 | 
						/* Standard string-based options. */
 | 
				
			||||||
	while ((p = strsep(&options, "|")) != NULL) {
 | 
						while ((p = strsep(&options, "|")) != NULL) {
 | 
				
			||||||
		int token;
 | 
							int token, rc;
 | 
				
			||||||
		substring_t args[MAX_OPT_ARGS];
 | 
							substring_t args[MAX_OPT_ARGS];
 | 
				
			||||||
 | 
							const char *arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!*p)
 | 
							if (!*p)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		token = match_token(p, tokens, args);
 | 
							token = match_token(p, tokens, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!opts) {
 | 
							if (token == Opt_labelsupport)	/* eaten and completely ignored */
 | 
				
			||||||
			opts = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL);
 | 
								continue;
 | 
				
			||||||
			if (!opts)
 | 
							arg = match_strdup(&args[0]);
 | 
				
			||||||
				return -ENOMEM;
 | 
							rc = selinux_add_opt(token, arg, mnt_opts);
 | 
				
			||||||
		}
 | 
							if (unlikely(rc)) {
 | 
				
			||||||
 | 
								kfree(arg);
 | 
				
			||||||
		switch (token) {
 | 
								if (*mnt_opts) {
 | 
				
			||||||
		case Opt_context:
 | 
									selinux_free_mnt_opts(*mnt_opts);
 | 
				
			||||||
			if (opts->context || opts->defcontext) {
 | 
									*mnt_opts = NULL;
 | 
				
			||||||
				rc = -EINVAL;
 | 
					 | 
				
			||||||
				pr_warn(SEL_MOUNT_FAIL_MSG);
 | 
					 | 
				
			||||||
				goto out_err;
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			opts->context = match_strdup(&args[0]);
 | 
								return rc;
 | 
				
			||||||
			if (!opts->context) {
 | 
					 | 
				
			||||||
				rc = -ENOMEM;
 | 
					 | 
				
			||||||
				goto out_err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case Opt_fscontext:
 | 
					 | 
				
			||||||
			if (opts->fscontext) {
 | 
					 | 
				
			||||||
				rc = -EINVAL;
 | 
					 | 
				
			||||||
				pr_warn(SEL_MOUNT_FAIL_MSG);
 | 
					 | 
				
			||||||
				goto out_err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			opts->fscontext = match_strdup(&args[0]);
 | 
					 | 
				
			||||||
			if (!opts->fscontext) {
 | 
					 | 
				
			||||||
				rc = -ENOMEM;
 | 
					 | 
				
			||||||
				goto out_err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case Opt_rootcontext:
 | 
					 | 
				
			||||||
			if (opts->rootcontext) {
 | 
					 | 
				
			||||||
				rc = -EINVAL;
 | 
					 | 
				
			||||||
				pr_warn(SEL_MOUNT_FAIL_MSG);
 | 
					 | 
				
			||||||
				goto out_err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			opts->rootcontext = match_strdup(&args[0]);
 | 
					 | 
				
			||||||
			if (!opts->rootcontext) {
 | 
					 | 
				
			||||||
				rc = -ENOMEM;
 | 
					 | 
				
			||||||
				goto out_err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case Opt_defcontext:
 | 
					 | 
				
			||||||
			if (opts->context || opts->defcontext) {
 | 
					 | 
				
			||||||
				rc = -EINVAL;
 | 
					 | 
				
			||||||
				pr_warn(SEL_MOUNT_FAIL_MSG);
 | 
					 | 
				
			||||||
				goto out_err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			opts->defcontext = match_strdup(&args[0]);
 | 
					 | 
				
			||||||
			if (!opts->defcontext) {
 | 
					 | 
				
			||||||
				rc = -ENOMEM;
 | 
					 | 
				
			||||||
				goto out_err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case Opt_labelsupport:
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			rc = -EINVAL;
 | 
					 | 
				
			||||||
			pr_warn("SELinux:  unknown mount option\n");
 | 
					 | 
				
			||||||
			goto out_err;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	*mnt_opts = opts;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
out_err:
 | 
					 | 
				
			||||||
	if (opts)
 | 
					 | 
				
			||||||
		selinux_free_mnt_opts(opts);
 | 
					 | 
				
			||||||
	return rc;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int show_sid(struct seq_file *m, u32 sid)
 | 
					static int show_sid(struct seq_file *m, u32 sid)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue