summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--security/tomoyo/common.h14
-rw-r--r--security/tomoyo/domain.c15
-rw-r--r--security/tomoyo/file.c26
-rw-r--r--security/tomoyo/group.c14
-rw-r--r--security/tomoyo/mount.c2
5 files changed, 48 insertions, 23 deletions
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 2ffad613855..04454cb7b24 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -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,8 +720,9 @@ 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_name_union *ptr);
+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,
const struct tomoyo_number_union *ptr);
@@ -736,8 +739,9 @@ 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_group *group);
+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,
const unsigned long max,
@@ -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. **********/
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 4e0101b0041..35388408e47 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -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)) {
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index f7877fa80f1..9d32f182301 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -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_name_union *ptr)
+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 =
diff --git a/security/tomoyo/group.c b/security/tomoyo/group.c
index 3f0a2abf65c..e94352ce723 100644
--- a/security/tomoyo/group.c
+++ b/security/tomoyo/group.c
@@ -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_group *group)
+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;
}
/**
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index cfeff871908..82bf8c2390b 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -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 =