Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f629636 authored by Tetsuo Handa's avatar Tetsuo Handa Committed by James Morris
Browse files

TOMOYO: Allow wildcard for execute permission.



Some applications create and execute programs dynamically. We need to accept
wildcard for execute permission because such programs contain random suffix
in their filenames. This patch loosens up regulation of string parameters.

Signed-off-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent c8c57e84
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -407,7 +407,7 @@ static int tomoyo_update_manager_entry(const char *manager,
			return -EINVAL;
			return -EINVAL;
		e.is_domain = true;
		e.is_domain = true;
	} else {
	} else {
		if (!tomoyo_is_correct_path(manager, 1, -1, -1))
		if (!tomoyo_is_correct_path(manager))
			return -EINVAL;
			return -EINVAL;
	}
	}
	e.manager = tomoyo_get_name(manager);
	e.manager = tomoyo_get_name(manager);
+3 −4
Original line number Original line Diff line number Diff line
@@ -672,16 +672,15 @@ bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
/* Check whether the domainname is correct. */
/* Check whether the domainname is correct. */
bool tomoyo_is_correct_domain(const unsigned char *domainname);
bool tomoyo_is_correct_domain(const unsigned char *domainname);
/* Check whether the token is correct. */
/* Check whether the token is correct. */
bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
bool tomoyo_is_correct_path(const char *filename);
			    const s8 pattern_type, const s8 end_type);
bool tomoyo_is_correct_word(const char *string);
/* Check whether the token can be a domainname. */
/* Check whether the token can be a domainname. */
bool tomoyo_is_domain_def(const unsigned char *buffer);
bool tomoyo_is_domain_def(const unsigned char *buffer);
bool tomoyo_parse_name_union(const char *filename,
bool tomoyo_parse_name_union(const char *filename,
			     struct tomoyo_name_union *ptr);
			     struct tomoyo_name_union *ptr);
/* Check whether the given filename matches the given path_group. */
/* Check whether the given filename matches the given path_group. */
bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
			       const struct tomoyo_path_group *group,
			       const struct tomoyo_path_group *group);
			       const bool may_use_pattern);
/* Check whether the given value matches the given number_group. */
/* Check whether the given value matches the given number_group. */
bool tomoyo_number_matches_group(const unsigned long min,
bool tomoyo_number_matches_group(const unsigned long min,
				 const unsigned long max,
				 const unsigned long max,
+11 −10
Original line number Original line Diff line number Diff line
@@ -131,11 +131,11 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
	struct tomoyo_domain_initializer_entry e = { .is_not = is_not };
	struct tomoyo_domain_initializer_entry e = { .is_not = is_not };
	int error = is_delete ? -ENOENT : -ENOMEM;
	int error = is_delete ? -ENOENT : -ENOMEM;


	if (!tomoyo_is_correct_path(program, 1, -1, -1))
	if (!tomoyo_is_correct_path(program))
		return -EINVAL; /* No patterns allowed. */
		return -EINVAL;
	if (domainname) {
	if (domainname) {
		if (!tomoyo_is_domain_def(domainname) &&
		if (!tomoyo_is_domain_def(domainname) &&
		    tomoyo_is_correct_path(domainname, 1, -1, -1))
		    tomoyo_is_correct_path(domainname))
			e.is_last_name = true;
			e.is_last_name = true;
		else if (!tomoyo_is_correct_domain(domainname))
		else if (!tomoyo_is_correct_domain(domainname))
			return -EINVAL;
			return -EINVAL;
@@ -342,12 +342,12 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
	int error = is_delete ? -ENOENT : -ENOMEM;
	int error = is_delete ? -ENOENT : -ENOMEM;


	if (!tomoyo_is_domain_def(domainname) &&
	if (!tomoyo_is_domain_def(domainname) &&
	    tomoyo_is_correct_path(domainname, 1, -1, -1))
	    tomoyo_is_correct_path(domainname))
		e.is_last_name = true;
		e.is_last_name = true;
	else if (!tomoyo_is_correct_domain(domainname))
	else if (!tomoyo_is_correct_domain(domainname))
		return -EINVAL;
		return -EINVAL;
	if (program) {
	if (program) {
		if (!tomoyo_is_correct_path(program, 1, -1, -1))
		if (!tomoyo_is_correct_path(program))
			return -EINVAL;
			return -EINVAL;
		e.program = tomoyo_get_name(program);
		e.program = tomoyo_get_name(program);
		if (!e.program)
		if (!e.program)
@@ -533,13 +533,14 @@ static int tomoyo_update_alias_entry(const char *original_name,
	struct tomoyo_alias_entry e = { };
	struct tomoyo_alias_entry e = { };
	int error = is_delete ? -ENOENT : -ENOMEM;
	int error = is_delete ? -ENOENT : -ENOMEM;


	if (!tomoyo_is_correct_path(original_name, 1, -1, -1) ||
	if (!tomoyo_is_correct_path(original_name) ||
	    !tomoyo_is_correct_path(aliased_name, 1, -1, -1))
	    !tomoyo_is_correct_path(aliased_name))
		return -EINVAL; /* No patterns allowed. */
		return -EINVAL;
	e.original_name = tomoyo_get_name(original_name);
	e.original_name = tomoyo_get_name(original_name);
	e.aliased_name = tomoyo_get_name(aliased_name);
	e.aliased_name = tomoyo_get_name(aliased_name);
	if (!e.original_name || !e.aliased_name)
	if (!e.original_name || !e.aliased_name ||
		goto out;
	    e.original_name->is_patterned || e.aliased_name->is_patterned)
		goto out; /* No patterns allowed. */
	if (mutex_lock_interruptible(&tomoyo_policy_lock))
	if (mutex_lock_interruptible(&tomoyo_policy_lock))
		goto out;
		goto out;
	list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
	list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
+11 −26
Original line number Original line Diff line number Diff line
@@ -65,23 +65,10 @@ bool tomoyo_compare_name_union(const struct tomoyo_path_info *name,
			       const struct tomoyo_name_union *ptr)
			       const struct tomoyo_name_union *ptr)
{
{
	if (ptr->is_group)
	if (ptr->is_group)
		return tomoyo_path_matches_group(name, ptr->group, 1);
		return tomoyo_path_matches_group(name, ptr->group);
	return tomoyo_path_matches_pattern(name, ptr->filename);
	return tomoyo_path_matches_pattern(name, ptr->filename);
}
}


static bool tomoyo_compare_name_union_pattern(const struct tomoyo_path_info
					      *name,
					      const struct tomoyo_name_union
					      *ptr, const bool may_use_pattern)
{
	if (ptr->is_group)
		return tomoyo_path_matches_group(name, ptr->group,
						 may_use_pattern);
	if (may_use_pattern || !ptr->filename->is_patterned)
		return tomoyo_path_matches_pattern(name, ptr->filename);
	return false;
}

void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
{
{
	if (ptr && ptr->is_group)
	if (ptr && ptr->is_group)
@@ -247,7 +234,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
	struct tomoyo_globally_readable_file_entry e = { };
	struct tomoyo_globally_readable_file_entry e = { };
	int error = is_delete ? -ENOENT : -ENOMEM;
	int error = is_delete ? -ENOENT : -ENOMEM;


	if (!tomoyo_is_correct_path(filename, 1, 0, -1))
	if (!tomoyo_is_correct_word(filename))
		return -EINVAL;
		return -EINVAL;
	e.filename = tomoyo_get_name(filename);
	e.filename = tomoyo_get_name(filename);
	if (!e.filename)
	if (!e.filename)
@@ -391,13 +378,14 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
					    const bool is_delete)
					    const bool is_delete)
{
{
	struct tomoyo_pattern_entry *ptr;
	struct tomoyo_pattern_entry *ptr;
	struct tomoyo_pattern_entry e = { .pattern = tomoyo_get_name(pattern) };
	struct tomoyo_pattern_entry e = { };
	int error = is_delete ? -ENOENT : -ENOMEM;
	int error = is_delete ? -ENOENT : -ENOMEM;


	if (!tomoyo_is_correct_word(pattern))
		return -EINVAL;
	e.pattern = tomoyo_get_name(pattern);
	if (!e.pattern)
	if (!e.pattern)
		return error;
		return error;
	if (!e.pattern->is_patterned)
		goto out;
	if (mutex_lock_interruptible(&tomoyo_policy_lock))
	if (mutex_lock_interruptible(&tomoyo_policy_lock))
		goto out;
		goto out;
	list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
	list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
@@ -543,7 +531,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
	struct tomoyo_no_rewrite_entry e = { };
	struct tomoyo_no_rewrite_entry e = { };
	int error = is_delete ? -ENOENT : -ENOMEM;
	int error = is_delete ? -ENOENT : -ENOMEM;


	if (!tomoyo_is_correct_path(pattern, 0, 0, 0))
	if (!tomoyo_is_correct_word(pattern))
		return -EINVAL;
		return -EINVAL;
	e.pattern = tomoyo_get_name(pattern);
	e.pattern = tomoyo_get_name(pattern);
	if (!e.pattern)
	if (!e.pattern)
@@ -690,7 +678,6 @@ static int tomoyo_update_file_acl(u8 perm, const char *filename,
 * @r:               Pointer to "struct tomoyo_request_info".
 * @r:               Pointer to "struct tomoyo_request_info".
 * @filename:        Filename to check.
 * @filename:        Filename to check.
 * @perm:            Permission.
 * @perm:            Permission.
 * @may_use_pattern: True if patterned ACL is permitted.
 *
 *
 * Returns 0 on success, -EPERM otherwise.
 * Returns 0 on success, -EPERM otherwise.
 *
 *
@@ -698,7 +685,7 @@ static int tomoyo_update_file_acl(u8 perm, const char *filename,
 */
 */
static int tomoyo_path_acl(const struct tomoyo_request_info *r,
static int tomoyo_path_acl(const struct tomoyo_request_info *r,
			   const struct tomoyo_path_info *filename,
			   const struct tomoyo_path_info *filename,
			   const u32 perm, const bool may_use_pattern)
			   const u32 perm)
{
{
	struct tomoyo_domain_info *domain = r->domain;
	struct tomoyo_domain_info *domain = r->domain;
	struct tomoyo_acl_info *ptr;
	struct tomoyo_acl_info *ptr;
@@ -710,8 +697,7 @@ static int tomoyo_path_acl(const struct tomoyo_request_info *r,
			continue;
			continue;
		acl = container_of(ptr, struct tomoyo_path_acl, head);
		acl = container_of(ptr, struct tomoyo_path_acl, head);
		if (!(acl->perm & perm) ||
		if (!(acl->perm & perm) ||
		    !tomoyo_compare_name_union_pattern(filename, &acl->name,
		    !tomoyo_compare_name_union(filename, &acl->name))
                                                       may_use_pattern))
			continue;
			continue;
		error = 0;
		error = 0;
		break;
		break;
@@ -756,7 +742,7 @@ static int tomoyo_file_perm(struct tomoyo_request_info *r,
	} else
	} else
		BUG();
		BUG();
	do {
	do {
		error = tomoyo_path_acl(r, filename, perm, mode != 1);
		error = tomoyo_path_acl(r, filename, perm);
		if (error && mode == 4 && !r->domain->ignore_global_allow_read
		if (error && mode == 4 && !r->domain->ignore_global_allow_read
		    && tomoyo_is_globally_readable_file(filename))
		    && tomoyo_is_globally_readable_file(filename))
			error = 0;
			error = 0;
@@ -764,7 +750,6 @@ static int tomoyo_file_perm(struct tomoyo_request_info *r,
			break;
			break;
		tomoyo_warn_log(r, "%s %s", msg, filename->name);
		tomoyo_warn_log(r, "%s %s", msg, filename->name);
		error = tomoyo_supervisor(r, "allow_%s %s\n", msg,
		error = tomoyo_supervisor(r, "allow_%s %s\n", msg,
					  mode == 1 ? filename->name :
					  tomoyo_file_pattern(filename));
					  tomoyo_file_pattern(filename));
		/*
		/*
                 * Do not retry for execute request, for alias may have
                 * Do not retry for execute request, for alias may have
@@ -1073,7 +1058,7 @@ static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,


 next:
 next:
	do {
	do {
		error = tomoyo_path_acl(r, filename, 1 << operation, 1);
		error = tomoyo_path_acl(r, filename, 1 << operation);
		if (!error)
		if (!error)
			break;
			break;
		msg = tomoyo_path2keyword(operation);
		msg = tomoyo_path2keyword(operation);
+1 −2
Original line number Original line Diff line number Diff line
@@ -24,8 +24,7 @@ struct tomoyo_number_group *tomoyo_get_number_group(const char *group_name)
	struct tomoyo_number_group *group = NULL;
	struct tomoyo_number_group *group = NULL;
	const struct tomoyo_path_info *saved_group_name;
	const struct tomoyo_path_info *saved_group_name;
	int error = -ENOMEM;
	int error = -ENOMEM;
	if (!tomoyo_is_correct_path(group_name, 0, 0, 0) ||
	if (!tomoyo_is_correct_word(group_name))
	    !group_name[0])
		return NULL;
		return NULL;
	saved_group_name = tomoyo_get_name(group_name);
	saved_group_name = tomoyo_get_name(group_name);
	if (!saved_group_name)
	if (!saved_group_name)
Loading