Skip to content

Commit

Permalink
TOMOYO: Allow wildcard for execute permission.
Browse files Browse the repository at this point in the history
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: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
  • Loading branch information
Tetsuo Handa authored and James Morris committed Aug 2, 2010
1 parent c8c57e8 commit 3f62963
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 151 deletions.
2 changes: 1 addition & 1 deletion security/tomoyo/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ static int tomoyo_update_manager_entry(const char *manager,
return -EINVAL;
e.is_domain = true;
} else {
if (!tomoyo_is_correct_path(manager, 1, -1, -1))
if (!tomoyo_is_correct_path(manager))
return -EINVAL;
}
e.manager = tomoyo_get_name(manager);
Expand Down
7 changes: 3 additions & 4 deletions security/tomoyo/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -672,16 +672,15 @@ bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
/* Check whether the domainname is correct. */
bool tomoyo_is_correct_domain(const unsigned char *domainname);
/* Check whether the token is correct. */
bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
const s8 pattern_type, const s8 end_type);
bool tomoyo_is_correct_path(const char *filename);
bool tomoyo_is_correct_word(const char *string);
/* Check whether the token can be a domainname. */
bool tomoyo_is_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_group *group,
const bool may_use_pattern);
const struct tomoyo_path_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,
Expand Down
21 changes: 11 additions & 10 deletions security/tomoyo/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
struct tomoyo_domain_initializer_entry e = { .is_not = is_not };
int error = is_delete ? -ENOENT : -ENOMEM;

if (!tomoyo_is_correct_path(program, 1, -1, -1))
return -EINVAL; /* No patterns allowed. */
if (!tomoyo_is_correct_path(program))
return -EINVAL;
if (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;
else if (!tomoyo_is_correct_domain(domainname))
return -EINVAL;
Expand Down Expand Up @@ -342,12 +342,12 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
int error = is_delete ? -ENOENT : -ENOMEM;

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

if (!tomoyo_is_correct_path(original_name, 1, -1, -1) ||
!tomoyo_is_correct_path(aliased_name, 1, -1, -1))
return -EINVAL; /* No patterns allowed. */
if (!tomoyo_is_correct_path(original_name) ||
!tomoyo_is_correct_path(aliased_name))
return -EINVAL;
e.original_name = tomoyo_get_name(original_name);
e.aliased_name = tomoyo_get_name(aliased_name);
if (!e.original_name || !e.aliased_name)
goto out;
if (!e.original_name || !e.aliased_name ||
e.original_name->is_patterned || e.aliased_name->is_patterned)
goto out; /* No patterns allowed. */
if (mutex_lock_interruptible(&tomoyo_policy_lock))
goto out;
list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
Expand Down
37 changes: 11 additions & 26 deletions security/tomoyo/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,10 @@ bool 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, 1);
return tomoyo_path_matches_group(name, ptr->group);
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)
{
if (ptr && ptr->is_group)
Expand Down Expand Up @@ -247,7 +234,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
struct tomoyo_globally_readable_file_entry e = { };
int error = is_delete ? -ENOENT : -ENOMEM;

if (!tomoyo_is_correct_path(filename, 1, 0, -1))
if (!tomoyo_is_correct_word(filename))
return -EINVAL;
e.filename = tomoyo_get_name(filename);
if (!e.filename)
Expand Down Expand Up @@ -391,13 +378,14 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
const bool is_delete)
{
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;

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

if (!tomoyo_is_correct_path(pattern, 0, 0, 0))
if (!tomoyo_is_correct_word(pattern))
return -EINVAL;
e.pattern = tomoyo_get_name(pattern);
if (!e.pattern)
Expand Down Expand Up @@ -690,15 +678,14 @@ static int tomoyo_update_file_acl(u8 perm, const char *filename,
* @r: Pointer to "struct tomoyo_request_info".
* @filename: Filename to check.
* @perm: Permission.
* @may_use_pattern: True if patterned ACL is permitted.
*
* Returns 0 on success, -EPERM otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_path_acl(const struct tomoyo_request_info *r,
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_acl_info *ptr;
Expand All @@ -710,8 +697,7 @@ static int tomoyo_path_acl(const struct tomoyo_request_info *r,
continue;
acl = container_of(ptr, struct tomoyo_path_acl, head);
if (!(acl->perm & perm) ||
!tomoyo_compare_name_union_pattern(filename, &acl->name,
may_use_pattern))
!tomoyo_compare_name_union(filename, &acl->name))
continue;
error = 0;
break;
Expand Down Expand Up @@ -756,15 +742,14 @@ static int tomoyo_file_perm(struct tomoyo_request_info *r,
} else
BUG();
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
&& tomoyo_is_globally_readable_file(filename))
error = 0;
if (!error)
break;
tomoyo_warn_log(r, "%s %s", msg, filename->name);
error = tomoyo_supervisor(r, "allow_%s %s\n", msg,
mode == 1 ? filename->name :
tomoyo_file_pattern(filename));
/*
* Do not retry for execute request, for alias may have
Expand Down Expand Up @@ -1073,7 +1058,7 @@ static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,

next:
do {
error = tomoyo_path_acl(r, filename, 1 << operation, 1);
error = tomoyo_path_acl(r, filename, 1 << operation);
if (!error)
break;
msg = tomoyo_path2keyword(operation);
Expand Down
3 changes: 1 addition & 2 deletions security/tomoyo/number_group.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ struct tomoyo_number_group *tomoyo_get_number_group(const char *group_name)
struct tomoyo_number_group *group = NULL;
const struct tomoyo_path_info *saved_group_name;
int error = -ENOMEM;
if (!tomoyo_is_correct_path(group_name, 0, 0, 0) ||
!group_name[0])
if (!tomoyo_is_correct_word(group_name))
return NULL;
saved_group_name = tomoyo_get_name(group_name);
if (!saved_group_name)
Expand Down
17 changes: 4 additions & 13 deletions security/tomoyo/path_group.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name)
struct tomoyo_path_group *group = NULL;
const struct tomoyo_path_info *saved_group_name;
int error = -ENOMEM;
if (!tomoyo_is_correct_path(group_name, 0, 0, 0) ||
!group_name[0])
if (!tomoyo_is_correct_word(group_name))
return NULL;
saved_group_name = tomoyo_get_name(group_name);
if (!saved_group_name)
Expand Down Expand Up @@ -141,29 +140,21 @@ bool tomoyo_read_path_group_policy(struct tomoyo_io_buffer *head)
*
* @pathname: The name of pathname.
* @group: Pointer to "struct tomoyo_path_group".
* @may_use_pattern: True if wild card is permitted.
*
* Returns true if @pathname matches pathnames in @group, false otherwise.
*
* Caller holds tomoyo_read_lock().
*/
bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
const struct tomoyo_path_group *group,
const bool may_use_pattern)
const struct tomoyo_path_group *group)
{
struct tomoyo_path_group_member *member;
bool matched = false;
list_for_each_entry_rcu(member, &group->member_list, list) {
if (member->is_deleted)
continue;
if (!member->member_name->is_patterned) {
if (tomoyo_pathcmp(pathname, member->member_name))
continue;
} else if (may_use_pattern) {
if (!tomoyo_path_matches_pattern(pathname,
member->member_name))
continue;
} else
if (!tomoyo_path_matches_pattern(pathname,
member->member_name))
continue;
matched = true;
break;
Expand Down
Loading

0 comments on commit 3f62963

Please sign in to comment.