Commit 484ca79c authored by Tetsuo Handa's avatar Tetsuo Handa Committed by James Morris
Browse files

TOMOYO: Use pathname specified by policy rather than execve()



Commit c9e69318 "TOMOYO: Allow wildcard for execute permission." changed execute
permission and domainname to accept wildcards. But tomoyo_find_next_domain()
was using pathname passed to execve() rather than pathname specified by the
execute permission. As a result, processes were not able to transit to domains
which contain wildcards in their domainnames.

This patch passes pathname specified by the execute permission back to
tomoyo_find_next_domain() so that processes can transit to domains which
contain wildcards in their domainnames.

Signed-off-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 4d6ec10b
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -246,6 +246,8 @@ struct tomoyo_request_info {
	union {
		struct {
			const struct tomoyo_path_info *filename;
			/* For using wildcards at tomoyo_find_next_domain(). */
			const struct tomoyo_path_info *matched_path;
			u8 operation;
		} path;
		struct {
@@ -718,7 +720,8 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
/* Print out of memory warning message. */
void tomoyo_warn_oom(const char *function);
/* Check whether the given name matches the given name_union. */
bool tomoyo_compare_name_union(const struct tomoyo_path_info *name,
const struct tomoyo_path_info *
tomoyo_compare_name_union(const struct tomoyo_path_info *name,
			  const struct tomoyo_name_union *ptr);
/* Check whether the given number matches the given number_union. */
bool tomoyo_compare_number_union(const unsigned long value,
@@ -736,7 +739,8 @@ bool tomoyo_domain_def(const unsigned char *buffer);
bool tomoyo_parse_name_union(const char *filename,
			     struct tomoyo_name_union *ptr);
/* Check whether the given filename matches the given path_group. */
bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
const struct tomoyo_path_info *
tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
			  const struct tomoyo_group *group);
/* Check whether the given value matches the given number_group. */
bool tomoyo_number_matches_group(const unsigned long min,
@@ -879,7 +883,7 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
						  const struct tomoyo_acl_head
						  *));
void tomoyo_check_acl(struct tomoyo_request_info *r,
		      bool (*check_entry) (const struct tomoyo_request_info *,
		      bool (*check_entry) (struct tomoyo_request_info *,
					   const struct tomoyo_acl_info *));

/********** External variable definitions. **********/
+14 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
}

void tomoyo_check_acl(struct tomoyo_request_info *r,
		      bool (*check_entry) (const struct tomoyo_request_info *,
		      bool (*check_entry) (struct tomoyo_request_info *,
					   const struct tomoyo_acl_info *))
{
	const struct tomoyo_domain_info *domain = r->domain;
@@ -465,6 +465,19 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
		goto retry;
	if (retval < 0)
		goto out;
	/*
	 * To be able to specify domainnames with wildcards, use the
	 * pathname specified in the policy (which may contain
	 * wildcard) rather than the pathname passed to execve()
	 * (which never contains wildcard).
	 */
	if (r.param.path.matched_path) {
		if (need_kfree)
			kfree(rn.name);
		need_kfree = false;
		/* This is OK because it is read only. */
		rn = *r.param.path.matched_path;
	}

	/* Calculate domain to transit to. */
	switch (tomoyo_transition_type(old_domain->domainname, &rn)) {
+17 −9
Original line number Diff line number Diff line
@@ -95,12 +95,15 @@ void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
		tomoyo_put_name(ptr->filename);
}

bool tomoyo_compare_name_union(const struct tomoyo_path_info *name,
const struct tomoyo_path_info *
tomoyo_compare_name_union(const struct tomoyo_path_info *name,
			  const struct tomoyo_name_union *ptr)
{
	if (ptr->is_group)
		return tomoyo_path_matches_group(name, ptr->group);
	return tomoyo_path_matches_pattern(name, ptr->filename);
	if (tomoyo_path_matches_pattern(name, ptr->filename))
		return ptr->filename;
	return NULL;
}

void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
@@ -504,16 +507,21 @@ int tomoyo_write_no_rewrite(char *data, const bool is_delete)
	return tomoyo_update_no_rewrite_entry(data, is_delete);
}

static bool tomoyo_check_path_acl(const struct tomoyo_request_info *r,
static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
				  const struct tomoyo_acl_info *ptr)
{
	const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl),
							 head);
	return (acl->perm & (1 << r->param.path.operation)) &&
		tomoyo_compare_name_union(r->param.path.filename, &acl->name);
	if (acl->perm & (1 << r->param.path.operation)) {
		r->param.path.matched_path =
			tomoyo_compare_name_union(r->param.path.filename,
						  &acl->name);
		return r->param.path.matched_path != NULL;
	}
	return false;
}

static bool tomoyo_check_path_number_acl(const struct tomoyo_request_info *r,
static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
					 const struct tomoyo_acl_info *ptr)
{
	const struct tomoyo_path_number_acl *acl =
@@ -525,7 +533,7 @@ static bool tomoyo_check_path_number_acl(const struct tomoyo_request_info *r,
					  &acl->name);
}

static bool tomoyo_check_path2_acl(const struct tomoyo_request_info *r,
static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
				   const struct tomoyo_acl_info *ptr)
{
	const struct tomoyo_path2_acl *acl =
@@ -536,7 +544,7 @@ static bool tomoyo_check_path2_acl(const struct tomoyo_request_info *r,
					     &acl->name2);
}

static bool tomoyo_check_mkdev_acl(const struct tomoyo_request_info *r,
static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
				const struct tomoyo_acl_info *ptr)
{
	const struct tomoyo_mkdev_acl *acl =
+7 −7
Original line number Diff line number Diff line
@@ -80,24 +80,24 @@ int tomoyo_write_group(char *data, const bool is_delete, const u8 type)
 * @pathname:        The name of pathname.
 * @group:           Pointer to "struct tomoyo_path_group".
 *
 * Returns true if @pathname matches pathnames in @group, false otherwise.
 * Returns matched member's pathname if @pathname matches pathnames in @group,
 * NULL otherwise.
 *
 * Caller holds tomoyo_read_lock().
 */
bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
const struct tomoyo_path_info *
tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
			  const struct tomoyo_group *group)
{
	struct tomoyo_path_group *member;
	bool matched = false;
	list_for_each_entry_rcu(member, &group->member_list, head.list) {
		if (member->head.is_deleted)
			continue;
		if (!tomoyo_path_matches_pattern(pathname, member->member_name))
			continue;
		matched = true;
		break;
		return member->member_name;
	}
	return matched;
	return NULL;
}

/**
+1 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
				 flags);
}

static bool tomoyo_check_mount_acl(const struct tomoyo_request_info *r,
static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
				   const struct tomoyo_acl_info *ptr)
{
	const struct tomoyo_mount_acl *acl =