Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 264548
b: refs/heads/master
c: 6bce98e
h: refs/heads/master
v: v3
  • Loading branch information
Tetsuo Handa authored and James Morris committed Sep 19, 2011
1 parent e5da409 commit e8437b3
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cc100551b4d92f47abebfa7c7918b2be71263b4a
refs/heads/master: 6bce98edc3365a8f780ff3944ac7992544c194fe
4 changes: 4 additions & 0 deletions trunk/security/tomoyo/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,10 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
case 0:
head->r.cond_index = 0;
head->r.cond_step++;
if (cond->transit) {
tomoyo_set_space(head);
tomoyo_set_string(head, cond->transit->name);
}
/* fall through */
case 1:
{
Expand Down
4 changes: 4 additions & 0 deletions trunk/security/tomoyo/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,7 @@ struct tomoyo_execve {
struct tomoyo_request_info r;
struct tomoyo_obj_info obj;
struct linux_binprm *bprm;
const struct tomoyo_path_info *transition;
/* For dumping argv[] and envp[]. */
struct tomoyo_page_dump dump;
/* For temporary use. */
Expand Down Expand Up @@ -650,6 +651,7 @@ struct tomoyo_condition {
u16 argc; /* Number of "struct tomoyo_argv". */
u16 envc; /* Number of "struct tomoyo_envp". */
u8 grant_log; /* One of values in "enum tomoyo_grant_log". */
const struct tomoyo_path_info *transit; /* Maybe NULL. */
/*
* struct tomoyo_condition_element condition[condc];
* struct tomoyo_number_union values[numbers_count];
Expand Down Expand Up @@ -956,6 +958,8 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
struct path *path, const int flag);
int tomoyo_close_control(struct tomoyo_io_buffer *head);
int tomoyo_env_perm(struct tomoyo_request_info *r, const char *env);
int tomoyo_execute_permission(struct tomoyo_request_info *r,
const struct tomoyo_path_info *filename);
int tomoyo_find_next_domain(struct linux_binprm *bprm);
int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
const u8 index);
Expand Down
50 changes: 47 additions & 3 deletions trunk/security/tomoyo/condition.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ static inline bool tomoyo_same_condition(const struct tomoyo_condition *a,
a->numbers_count == b->numbers_count &&
a->names_count == b->names_count &&
a->argc == b->argc && a->envc == b->envc &&
a->grant_log == b->grant_log &&
a->grant_log == b->grant_log && a->transit == b->transit &&
!memcmp(a + 1, b + 1, a->size - sizeof(*a));
}

Expand Down Expand Up @@ -428,6 +428,46 @@ static struct tomoyo_condition *tomoyo_commit_condition
return entry;
}

/**
* tomoyo_get_transit_preference - Parse domain transition preference for execve().
*
* @param: Pointer to "struct tomoyo_acl_param".
* @e: Pointer to "struct tomoyo_condition".
*
* Returns the condition string part.
*/
static char *tomoyo_get_transit_preference(struct tomoyo_acl_param *param,
struct tomoyo_condition *e)
{
char * const pos = param->data;
bool flag;
if (*pos == '<') {
e->transit = tomoyo_get_domainname(param);
goto done;
}
{
char *cp = strchr(pos, ' ');
if (cp)
*cp = '\0';
flag = tomoyo_correct_path(pos) || !strcmp(pos, "keep") ||
!strcmp(pos, "initialize") || !strcmp(pos, "reset") ||
!strcmp(pos, "child") || !strcmp(pos, "parent");
if (cp)
*cp = ' ';
}
if (!flag)
return pos;
e->transit = tomoyo_get_name(tomoyo_read_token(param));
done:
if (e->transit)
return param->data;
/*
* Return a bad read-only condition string that will let
* tomoyo_get_condition() return NULL.
*/
return "/";
}

/**
* tomoyo_get_condition - Parse condition part.
*
Expand All @@ -444,7 +484,8 @@ struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param)
struct tomoyo_argv *argv = NULL;
struct tomoyo_envp *envp = NULL;
struct tomoyo_condition e = { };
char * const start_of_string = param->data;
char * const start_of_string =
tomoyo_get_transit_preference(param, &e);
char * const end_of_string = start_of_string + strlen(start_of_string);
char *pos;
rerun:
Expand Down Expand Up @@ -608,8 +649,9 @@ struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param)
+ e.envc * sizeof(struct tomoyo_envp);
entry = kzalloc(e.size, GFP_NOFS);
if (!entry)
return NULL;
goto out2;
*entry = e;
e.transit = NULL;
condp = (struct tomoyo_condition_element *) (entry + 1);
numbers_p = (struct tomoyo_number_union *) (condp + e.condc);
names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count);
Expand All @@ -636,6 +678,8 @@ struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param)
tomoyo_del_condition(&entry->head.list);
kfree(entry);
}
out2:
tomoyo_put_name(e.transit);
return NULL;
}

Expand Down
53 changes: 50 additions & 3 deletions trunk/security/tomoyo/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
new_entry->cond = tomoyo_get_condition(param);
if (!new_entry->cond)
return -EINVAL;
/*
* Domain transition preference is allowed for only
* "file execute" entries.
*/
if (new_entry->cond->transit &&
!(new_entry->type == TOMOYO_TYPE_PATH_ACL &&
container_of(new_entry, struct tomoyo_path_acl, head)
->perm == 1 << TOMOYO_TYPE_EXECUTE))
goto out;
}
if (mutex_lock_interruptible(&tomoyo_policy_lock))
goto out;
Expand Down Expand Up @@ -707,8 +716,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
}

/* Check execute permission. */
retval = tomoyo_path_permission(&ee->r, TOMOYO_TYPE_EXECUTE,
candidate);
retval = tomoyo_execute_permission(&ee->r, candidate);
if (retval == TOMOYO_RETRY_REQUEST)
goto retry;
if (retval < 0)
Expand All @@ -722,10 +730,45 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
if (ee->r.param.path.matched_path)
candidate = ee->r.param.path.matched_path;

/* Calculate domain to transit to. */
/*
* Check for domain transition preference if "file execute" matched.
* If preference is given, make do_execve() fail if domain transition
* has failed, for domain transition preference should be used with
* destination domain defined.
*/
if (ee->transition) {
const char *domainname = ee->transition->name;
reject_on_transition_failure = true;
if (!strcmp(domainname, "keep"))
goto force_keep_domain;
if (!strcmp(domainname, "child"))
goto force_child_domain;
if (!strcmp(domainname, "reset"))
goto force_reset_domain;
if (!strcmp(domainname, "initialize"))
goto force_initialize_domain;
if (!strcmp(domainname, "parent")) {
char *cp;
strncpy(ee->tmp, old_domain->domainname->name,
TOMOYO_EXEC_TMPSIZE - 1);
cp = strrchr(ee->tmp, ' ');
if (cp)
*cp = '\0';
} else if (*domainname == '<')
strncpy(ee->tmp, domainname, TOMOYO_EXEC_TMPSIZE - 1);
else
snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
old_domain->domainname->name, domainname);
goto force_jump_domain;
}
/*
* No domain transition preference specified.
* Calculate domain to transit to.
*/
switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname,
candidate)) {
case TOMOYO_TRANSITION_CONTROL_RESET:
force_reset_domain:
/* Transit to the root of specified namespace. */
snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>",
candidate->name);
Expand All @@ -736,11 +779,13 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
reject_on_transition_failure = true;
break;
case TOMOYO_TRANSITION_CONTROL_INITIALIZE:
force_initialize_domain:
/* Transit to the child of current namespace's root. */
snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
old_domain->ns->name, candidate->name);
break;
case TOMOYO_TRANSITION_CONTROL_KEEP:
force_keep_domain:
/* Keep current domain. */
domain = old_domain;
break;
Expand All @@ -756,11 +801,13 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
domain = old_domain;
break;
}
force_child_domain:
/* Normal domain transition. */
snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
old_domain->domainname->name, candidate->name);
break;
}
force_jump_domain:
if (!domain)
domain = tomoyo_assign_domain(ee->tmp, true);
if (domain)
Expand Down
38 changes: 32 additions & 6 deletions trunk/security/tomoyo/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,15 +570,41 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
do {
tomoyo_check_acl(r, tomoyo_check_path_acl);
error = tomoyo_audit_path_log(r);
/*
* Do not retry for execute request, for alias may have
* changed.
*/
} while (error == TOMOYO_RETRY_REQUEST &&
operation != TOMOYO_TYPE_EXECUTE);
} while (error == TOMOYO_RETRY_REQUEST);
return error;
}

/**
* tomoyo_execute_permission - Check permission for execute operation.
*
* @r: Pointer to "struct tomoyo_request_info".
* @filename: Filename to check.
*
* Returns 0 on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
int tomoyo_execute_permission(struct tomoyo_request_info *r,
const struct tomoyo_path_info *filename)
{
/*
* Unlike other permission checks, this check is done regardless of
* profile mode settings in order to check for domain transition
* preference.
*/
r->type = TOMOYO_MAC_FILE_EXECUTE;
r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
r->param_type = TOMOYO_TYPE_PATH_ACL;
r->param.path.filename = filename;
r->param.path.operation = TOMOYO_TYPE_EXECUTE;
tomoyo_check_acl(r, tomoyo_check_path_acl);
r->ee->transition = r->matched_acl && r->matched_acl->cond ?
r->matched_acl->cond->transit : NULL;
if (r->mode != TOMOYO_CONFIG_DISABLED)
return tomoyo_audit_path_log(r);
return 0;
}

/**
* tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry.
*
Expand Down

0 comments on commit e8437b3

Please sign in to comment.