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: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
parent
4d6ec10bb4
commit
484ca79c65
5 changed files with 48 additions and 23 deletions
|
@ -246,6 +246,8 @@ struct tomoyo_request_info {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
const struct tomoyo_path_info *filename;
|
const struct tomoyo_path_info *filename;
|
||||||
|
/* For using wildcards at tomoyo_find_next_domain(). */
|
||||||
|
const struct tomoyo_path_info *matched_path;
|
||||||
u8 operation;
|
u8 operation;
|
||||||
} path;
|
} path;
|
||||||
struct {
|
struct {
|
||||||
|
@ -718,7 +720,8 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
|
||||||
/* Print out of memory warning message. */
|
/* Print out of memory warning message. */
|
||||||
void tomoyo_warn_oom(const char *function);
|
void tomoyo_warn_oom(const char *function);
|
||||||
/* Check whether the given name matches the given name_union. */
|
/* 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);
|
const struct tomoyo_name_union *ptr);
|
||||||
/* Check whether the given number matches the given number_union. */
|
/* Check whether the given number matches the given number_union. */
|
||||||
bool tomoyo_compare_number_union(const unsigned long value,
|
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,
|
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,
|
const struct tomoyo_path_info *
|
||||||
|
tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
|
||||||
const struct tomoyo_group *group);
|
const struct tomoyo_group *group);
|
||||||
/* 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,
|
||||||
|
@ -879,7 +883,7 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
|
||||||
const struct tomoyo_acl_head
|
const struct tomoyo_acl_head
|
||||||
*));
|
*));
|
||||||
void tomoyo_check_acl(struct tomoyo_request_info *r,
|
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_acl_info *));
|
||||||
|
|
||||||
/********** External variable definitions. **********/
|
/********** External variable definitions. **********/
|
||||||
|
|
|
@ -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,
|
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_acl_info *))
|
||||||
{
|
{
|
||||||
const struct tomoyo_domain_info *domain = r->domain;
|
const struct tomoyo_domain_info *domain = r->domain;
|
||||||
|
@ -465,6 +465,19 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
|
||||||
goto retry;
|
goto retry;
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto out;
|
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. */
|
/* Calculate domain to transit to. */
|
||||||
switch (tomoyo_transition_type(old_domain->domainname, &rn)) {
|
switch (tomoyo_transition_type(old_domain->domainname, &rn)) {
|
||||||
|
|
|
@ -95,12 +95,15 @@ void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
|
||||||
tomoyo_put_name(ptr->filename);
|
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)
|
const struct tomoyo_name_union *ptr)
|
||||||
{
|
{
|
||||||
if (ptr->is_group)
|
if (ptr->is_group)
|
||||||
return tomoyo_path_matches_group(name, ptr->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)
|
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);
|
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_acl_info *ptr)
|
||||||
{
|
{
|
||||||
const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl),
|
const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl),
|
||||||
head);
|
head);
|
||||||
return (acl->perm & (1 << r->param.path.operation)) &&
|
if (acl->perm & (1 << r->param.path.operation)) {
|
||||||
tomoyo_compare_name_union(r->param.path.filename, &acl->name);
|
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_acl_info *ptr)
|
||||||
{
|
{
|
||||||
const struct tomoyo_path_number_acl *acl =
|
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);
|
&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_acl_info *ptr)
|
||||||
{
|
{
|
||||||
const struct tomoyo_path2_acl *acl =
|
const struct tomoyo_path2_acl *acl =
|
||||||
|
@ -536,7 +544,7 @@ static bool tomoyo_check_path2_acl(const struct tomoyo_request_info *r,
|
||||||
&acl->name2);
|
&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_acl_info *ptr)
|
||||||
{
|
{
|
||||||
const struct tomoyo_mkdev_acl *acl =
|
const struct tomoyo_mkdev_acl *acl =
|
||||||
|
|
|
@ -80,24 +80,24 @@ int tomoyo_write_group(char *data, const bool is_delete, const u8 type)
|
||||||
* @pathname: The name of pathname.
|
* @pathname: The name of pathname.
|
||||||
* @group: Pointer to "struct tomoyo_path_group".
|
* @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().
|
* 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)
|
const struct tomoyo_group *group)
|
||||||
{
|
{
|
||||||
struct tomoyo_path_group *member;
|
struct tomoyo_path_group *member;
|
||||||
bool matched = false;
|
|
||||||
list_for_each_entry_rcu(member, &group->member_list, head.list) {
|
list_for_each_entry_rcu(member, &group->member_list, head.list) {
|
||||||
if (member->head.is_deleted)
|
if (member->head.is_deleted)
|
||||||
continue;
|
continue;
|
||||||
if (!tomoyo_path_matches_pattern(pathname, member->member_name))
|
if (!tomoyo_path_matches_pattern(pathname, member->member_name))
|
||||||
continue;
|
continue;
|
||||||
matched = true;
|
return member->member_name;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return matched;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -60,7 +60,7 @@ static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
|
||||||
flags);
|
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_acl_info *ptr)
|
||||||
{
|
{
|
||||||
const struct tomoyo_mount_acl *acl =
|
const struct tomoyo_mount_acl *acl =
|
||||||
|
|
Loading…
Add table
Reference in a new issue