TOMOYO: Use common code for domain transition control.
Use common code for "initialize_domain"/"no_initialize_domain"/"keep_domain"/ "no_keep_domain" keywords. 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
0617c7ff34
commit
5448ec4f50
|
@ -1150,6 +1150,15 @@ static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = {
|
||||
[TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE]
|
||||
= TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN,
|
||||
[TOMOYO_TRANSITION_CONTROL_INITIALIZE]
|
||||
= TOMOYO_KEYWORD_INITIALIZE_DOMAIN,
|
||||
[TOMOYO_TRANSITION_CONTROL_NO_KEEP] = TOMOYO_KEYWORD_NO_KEEP_DOMAIN,
|
||||
[TOMOYO_TRANSITION_CONTROL_KEEP] = TOMOYO_KEYWORD_KEEP_DOMAIN
|
||||
};
|
||||
|
||||
/**
|
||||
* tomoyo_write_exception_policy - Write exception policy.
|
||||
*
|
||||
|
@ -1163,18 +1172,13 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
|
|||
{
|
||||
char *data = head->write_buf;
|
||||
bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE);
|
||||
u8 i;
|
||||
|
||||
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_KEEP_DOMAIN))
|
||||
return tomoyo_write_domain_keeper_policy(data, false,
|
||||
is_delete);
|
||||
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_KEEP_DOMAIN))
|
||||
return tomoyo_write_domain_keeper_policy(data, true, is_delete);
|
||||
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_INITIALIZE_DOMAIN))
|
||||
return tomoyo_write_domain_initializer_policy(data, false,
|
||||
is_delete);
|
||||
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN))
|
||||
return tomoyo_write_domain_initializer_policy(data, true,
|
||||
is_delete);
|
||||
for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) {
|
||||
if (tomoyo_str_starts(&data, tomoyo_transition_type[i]))
|
||||
return tomoyo_write_transition_control(data, is_delete,
|
||||
i);
|
||||
}
|
||||
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_AGGREGATOR))
|
||||
return tomoyo_write_aggregator_policy(data, is_delete);
|
||||
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_READ))
|
||||
|
@ -1296,32 +1300,17 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
|
|||
if (acl->is_deleted)
|
||||
continue;
|
||||
switch (idx) {
|
||||
case TOMOYO_ID_DOMAIN_KEEPER:
|
||||
case TOMOYO_ID_TRANSITION_CONTROL:
|
||||
{
|
||||
struct tomoyo_domain_keeper_entry *ptr =
|
||||
struct tomoyo_transition_control *ptr =
|
||||
container_of(acl, typeof(*ptr), head);
|
||||
w[0] = ptr->is_not ?
|
||||
TOMOYO_KEYWORD_NO_KEEP_DOMAIN :
|
||||
TOMOYO_KEYWORD_KEEP_DOMAIN;
|
||||
if (ptr->program) {
|
||||
w[0] = tomoyo_transition_type[ptr->type];
|
||||
if (ptr->program)
|
||||
w[1] = ptr->program->name;
|
||||
w[2] = " from ";
|
||||
}
|
||||
if (ptr->domainname)
|
||||
w[3] = ptr->domainname->name;
|
||||
}
|
||||
break;
|
||||
case TOMOYO_ID_DOMAIN_INITIALIZER:
|
||||
{
|
||||
struct tomoyo_domain_initializer_entry *ptr =
|
||||
container_of(acl, typeof(*ptr), head);
|
||||
w[0] = ptr->is_not ?
|
||||
TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN :
|
||||
TOMOYO_KEYWORD_INITIALIZE_DOMAIN;
|
||||
w[1] = ptr->program->name;
|
||||
if (ptr->domainname) {
|
||||
if (w[1][0] && w[3][0])
|
||||
w[2] = " from ";
|
||||
w[3] = ptr->domainname->name;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TOMOYO_ID_GLOBALLY_READABLE:
|
||||
|
|
|
@ -50,8 +50,7 @@ enum tomoyo_policy_id {
|
|||
TOMOYO_ID_GROUP,
|
||||
TOMOYO_ID_PATH_GROUP,
|
||||
TOMOYO_ID_NUMBER_GROUP,
|
||||
TOMOYO_ID_DOMAIN_INITIALIZER,
|
||||
TOMOYO_ID_DOMAIN_KEEPER,
|
||||
TOMOYO_ID_TRANSITION_CONTROL,
|
||||
TOMOYO_ID_AGGREGATOR,
|
||||
TOMOYO_ID_GLOBALLY_READABLE,
|
||||
TOMOYO_ID_PATTERN,
|
||||
|
@ -97,6 +96,15 @@ enum tomoyo_group_id {
|
|||
#define TOMOYO_VALUE_TYPE_OCTAL 2
|
||||
#define TOMOYO_VALUE_TYPE_HEXADECIMAL 3
|
||||
|
||||
enum tomoyo_transition_type {
|
||||
/* Do not change this order, */
|
||||
TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE,
|
||||
TOMOYO_TRANSITION_CONTROL_INITIALIZE,
|
||||
TOMOYO_TRANSITION_CONTROL_NO_KEEP,
|
||||
TOMOYO_TRANSITION_CONTROL_KEEP,
|
||||
TOMOYO_MAX_TRANSITION_TYPE
|
||||
};
|
||||
|
||||
/* Index numbers for Access Controls. */
|
||||
enum tomoyo_acl_entry_type_index {
|
||||
TOMOYO_TYPE_PATH_ACL,
|
||||
|
@ -619,50 +627,26 @@ struct tomoyo_no_rewrite_entry {
|
|||
};
|
||||
|
||||
/*
|
||||
* tomoyo_domain_initializer_entry is a structure which is used for holding
|
||||
* "initialize_domain" and "no_initialize_domain" entries.
|
||||
* tomoyo_transition_control is a structure which is used for holding
|
||||
* "initialize_domain"/"no_initialize_domain"/"keep_domain"/"no_keep_domain"
|
||||
* entries.
|
||||
* It has following fields.
|
||||
*
|
||||
* (1) "head" is "struct tomoyo_acl_head".
|
||||
* (2) "is_not" is a bool which is true if "no_initialize_domain", false
|
||||
* otherwise.
|
||||
* (3) "is_last_name" is a bool which is true if "domainname" is "the last
|
||||
* component of a domainname", false otherwise.
|
||||
* (4) "domainname" which is "a domainname" or "the last component of a
|
||||
* domainname". This field is NULL if "from" clause is not specified.
|
||||
* (5) "program" which is a program's pathname.
|
||||
*/
|
||||
struct tomoyo_domain_initializer_entry {
|
||||
struct tomoyo_acl_head head;
|
||||
bool is_not; /* True if this entry is "no_initialize_domain". */
|
||||
/* True if the domainname is tomoyo_get_last_name(). */
|
||||
bool is_last_name;
|
||||
const struct tomoyo_path_info *domainname; /* This may be NULL */
|
||||
const struct tomoyo_path_info *program;
|
||||
};
|
||||
|
||||
/*
|
||||
* tomoyo_domain_keeper_entry is a structure which is used for holding
|
||||
* "keep_domain" and "no_keep_domain" entries.
|
||||
* It has following fields.
|
||||
*
|
||||
* (1) "head" is "struct tomoyo_acl_head".
|
||||
* (2) "is_not" is a bool which is true if "no_initialize_domain", false
|
||||
* otherwise.
|
||||
* (2) "type" is type of this entry.
|
||||
* (3) "is_last_name" is a bool which is true if "domainname" is "the last
|
||||
* component of a domainname", false otherwise.
|
||||
* (4) "domainname" which is "a domainname" or "the last component of a
|
||||
* domainname".
|
||||
* (5) "program" which is a program's pathname.
|
||||
* This field is NULL if "from" clause is not specified.
|
||||
*/
|
||||
struct tomoyo_domain_keeper_entry {
|
||||
struct tomoyo_transition_control {
|
||||
struct tomoyo_acl_head head;
|
||||
bool is_not; /* True if this entry is "no_keep_domain". */
|
||||
u8 type; /* One of values in "enum tomoyo_transition_type". */
|
||||
/* True if the domainname is tomoyo_get_last_name(). */
|
||||
bool is_last_name;
|
||||
const struct tomoyo_path_info *domainname;
|
||||
const struct tomoyo_path_info *program; /* This may be NULL */
|
||||
const struct tomoyo_path_info *domainname; /* Maybe NULL */
|
||||
const struct tomoyo_path_info *program; /* Maybe NULL */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -793,15 +777,8 @@ int tomoyo_mount_permission(char *dev_name, struct path *path, char *type,
|
|||
unsigned long flags, void *data_page);
|
||||
/* Create "aggregator" entry in exception policy. */
|
||||
int tomoyo_write_aggregator_policy(char *data, const bool is_delete);
|
||||
/*
|
||||
* Create "initialize_domain" and "no_initialize_domain" entry
|
||||
* in exception policy.
|
||||
*/
|
||||
int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
|
||||
const bool is_delete);
|
||||
/* Create "keep_domain" and "no_keep_domain" entry in exception policy. */
|
||||
int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
|
||||
const bool is_delete);
|
||||
int tomoyo_write_transition_control(char *data, const bool is_delete,
|
||||
const u8 type);
|
||||
/*
|
||||
* Create "allow_read/write", "allow_execute", "allow_read", "allow_write",
|
||||
* "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir",
|
||||
|
@ -922,6 +899,7 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
|
|||
void tomoyo_check_acl(struct tomoyo_request_info *r,
|
||||
bool (*check_entry) (const struct tomoyo_request_info *,
|
||||
const struct tomoyo_acl_info *));
|
||||
const char *tomoyo_last_word(const char *name);
|
||||
|
||||
/********** External variable definitions. **********/
|
||||
|
||||
|
|
|
@ -150,173 +150,39 @@ const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain)
|
|||
return cp0;
|
||||
}
|
||||
|
||||
static bool tomoyo_same_domain_initializer_entry(const struct tomoyo_acl_head *
|
||||
static bool tomoyo_same_transition_control_entry(const struct tomoyo_acl_head *
|
||||
a,
|
||||
const struct tomoyo_acl_head *
|
||||
b)
|
||||
{
|
||||
const struct tomoyo_domain_initializer_entry *p1 =
|
||||
container_of(a, typeof(*p1), head);
|
||||
const struct tomoyo_domain_initializer_entry *p2 =
|
||||
container_of(b, typeof(*p2), head);
|
||||
return p1->is_not == p2->is_not && p1->is_last_name == p2->is_last_name
|
||||
const struct tomoyo_transition_control *p1 = container_of(a,
|
||||
typeof(*p1),
|
||||
head);
|
||||
const struct tomoyo_transition_control *p2 = container_of(b,
|
||||
typeof(*p2),
|
||||
head);
|
||||
return p1->type == p2->type && p1->is_last_name == p2->is_last_name
|
||||
&& p1->domainname == p2->domainname
|
||||
&& p1->program == p2->program;
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_update_domain_initializer_entry - Update "struct tomoyo_domain_initializer_entry" list.
|
||||
* tomoyo_update_transition_control_entry - Update "struct tomoyo_transition_control" list.
|
||||
*
|
||||
* @domainname: The name of domain. Maybe NULL.
|
||||
* @program: The name of program.
|
||||
* @is_not: True if it is "no_initialize_domain" entry.
|
||||
* @is_delete: True if it is a delete request.
|
||||
*
|
||||
* Returns 0 on success, negative value otherwise.
|
||||
*
|
||||
* Caller holds tomoyo_read_lock().
|
||||
*/
|
||||
static int tomoyo_update_domain_initializer_entry(const char *domainname,
|
||||
const char *program,
|
||||
const bool is_not,
|
||||
const bool is_delete)
|
||||
{
|
||||
struct tomoyo_domain_initializer_entry e = { .is_not = is_not };
|
||||
int error = is_delete ? -ENOENT : -ENOMEM;
|
||||
|
||||
if (!tomoyo_correct_path(program))
|
||||
return -EINVAL;
|
||||
if (domainname) {
|
||||
if (!tomoyo_domain_def(domainname) &&
|
||||
tomoyo_correct_path(domainname))
|
||||
e.is_last_name = true;
|
||||
else if (!tomoyo_correct_domain(domainname))
|
||||
return -EINVAL;
|
||||
e.domainname = tomoyo_get_name(domainname);
|
||||
if (!e.domainname)
|
||||
goto out;
|
||||
}
|
||||
e.program = tomoyo_get_name(program);
|
||||
if (!e.program)
|
||||
goto out;
|
||||
error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
|
||||
&tomoyo_policy_list
|
||||
[TOMOYO_ID_DOMAIN_INITIALIZER],
|
||||
tomoyo_same_domain_initializer_entry);
|
||||
out:
|
||||
tomoyo_put_name(e.domainname);
|
||||
tomoyo_put_name(e.program);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_write_domain_initializer_policy - Write "struct tomoyo_domain_initializer_entry" list.
|
||||
*
|
||||
* @data: String to parse.
|
||||
* @is_not: True if it is "no_initialize_domain" entry.
|
||||
* @is_delete: True if it is a delete request.
|
||||
*
|
||||
* Returns 0 on success, negative value otherwise.
|
||||
*
|
||||
* Caller holds tomoyo_read_lock().
|
||||
*/
|
||||
int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
|
||||
const bool is_delete)
|
||||
{
|
||||
char *cp = strstr(data, " from ");
|
||||
|
||||
if (cp) {
|
||||
*cp = '\0';
|
||||
return tomoyo_update_domain_initializer_entry(cp + 6, data,
|
||||
is_not,
|
||||
is_delete);
|
||||
}
|
||||
return tomoyo_update_domain_initializer_entry(NULL, data, is_not,
|
||||
is_delete);
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_domain_initializer - Check whether the given program causes domainname reinitialization.
|
||||
*
|
||||
* @domainname: The name of domain.
|
||||
* @program: The name of program.
|
||||
* @last_name: The last component of @domainname.
|
||||
*
|
||||
* Returns true if executing @program reinitializes domain transition,
|
||||
* false otherwise.
|
||||
*
|
||||
* Caller holds tomoyo_read_lock().
|
||||
*/
|
||||
static bool tomoyo_domain_initializer(const struct tomoyo_path_info *
|
||||
domainname,
|
||||
const struct tomoyo_path_info *program,
|
||||
const struct tomoyo_path_info *
|
||||
last_name)
|
||||
{
|
||||
struct tomoyo_domain_initializer_entry *ptr;
|
||||
bool flag = false;
|
||||
|
||||
list_for_each_entry_rcu(ptr, &tomoyo_policy_list
|
||||
[TOMOYO_ID_DOMAIN_INITIALIZER], head.list) {
|
||||
if (ptr->head.is_deleted)
|
||||
continue;
|
||||
if (ptr->domainname) {
|
||||
if (!ptr->is_last_name) {
|
||||
if (ptr->domainname != domainname)
|
||||
continue;
|
||||
} else {
|
||||
if (tomoyo_pathcmp(ptr->domainname, last_name))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (tomoyo_pathcmp(ptr->program, program))
|
||||
continue;
|
||||
if (ptr->is_not) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
flag = true;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
static bool tomoyo_same_domain_keeper_entry(const struct tomoyo_acl_head *a,
|
||||
const struct tomoyo_acl_head *b)
|
||||
{
|
||||
const struct tomoyo_domain_keeper_entry *p1 =
|
||||
container_of(a, typeof(*p1), head);
|
||||
const struct tomoyo_domain_keeper_entry *p2 =
|
||||
container_of(b, typeof(*p2), head);
|
||||
return p1->is_not == p2->is_not && p1->is_last_name == p2->is_last_name
|
||||
&& p1->domainname == p2->domainname
|
||||
&& p1->program == p2->program;
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_update_domain_keeper_entry - Update "struct tomoyo_domain_keeper_entry" list.
|
||||
*
|
||||
* @domainname: The name of domain.
|
||||
* @program: The name of program. Maybe NULL.
|
||||
* @is_not: True if it is "no_keep_domain" entry.
|
||||
* @type: Type of transition.
|
||||
* @is_delete: True if it is a delete request.
|
||||
*
|
||||
* Returns 0 on success, negative value otherwise.
|
||||
*
|
||||
* Caller holds tomoyo_read_lock().
|
||||
*/
|
||||
static int tomoyo_update_domain_keeper_entry(const char *domainname,
|
||||
static int tomoyo_update_transition_control_entry(const char *domainname,
|
||||
const char *program,
|
||||
const bool is_not,
|
||||
const u8 type,
|
||||
const bool is_delete)
|
||||
{
|
||||
struct tomoyo_domain_keeper_entry e = { .is_not = is_not };
|
||||
struct tomoyo_transition_control e = { .type = type };
|
||||
int error = is_delete ? -ENOENT : -ENOMEM;
|
||||
|
||||
if (!tomoyo_domain_def(domainname) &&
|
||||
tomoyo_correct_path(domainname))
|
||||
e.is_last_name = true;
|
||||
else if (!tomoyo_correct_domain(domainname))
|
||||
return -EINVAL;
|
||||
if (program) {
|
||||
if (!tomoyo_correct_path(program))
|
||||
return -EINVAL;
|
||||
|
@ -324,13 +190,20 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
|
|||
if (!e.program)
|
||||
goto out;
|
||||
}
|
||||
if (domainname) {
|
||||
if (!tomoyo_correct_domain(domainname)) {
|
||||
if (!tomoyo_correct_path(domainname))
|
||||
goto out;
|
||||
e.is_last_name = true;
|
||||
}
|
||||
e.domainname = tomoyo_get_name(domainname);
|
||||
if (!e.domainname)
|
||||
goto out;
|
||||
}
|
||||
error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
|
||||
&tomoyo_policy_list
|
||||
[TOMOYO_ID_DOMAIN_KEEPER],
|
||||
tomoyo_same_domain_keeper_entry);
|
||||
[TOMOYO_ID_TRANSITION_CONTROL],
|
||||
tomoyo_same_transition_control_entry);
|
||||
out:
|
||||
tomoyo_put_name(e.domainname);
|
||||
tomoyo_put_name(e.program);
|
||||
|
@ -338,67 +211,85 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
|
|||
}
|
||||
|
||||
/**
|
||||
* tomoyo_write_domain_keeper_policy - Write "struct tomoyo_domain_keeper_entry" list.
|
||||
* tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list.
|
||||
*
|
||||
* @data: String to parse.
|
||||
* @is_not: True if it is "no_keep_domain" entry.
|
||||
* @is_delete: True if it is a delete request.
|
||||
* @type: Type of this entry.
|
||||
*
|
||||
* Caller holds tomoyo_read_lock().
|
||||
* Returns 0 on success, negative value otherwise.
|
||||
*/
|
||||
int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
|
||||
const bool is_delete)
|
||||
int tomoyo_write_transition_control(char *data, const bool is_delete,
|
||||
const u8 type)
|
||||
{
|
||||
char *cp = strstr(data, " from ");
|
||||
|
||||
if (cp) {
|
||||
*cp = '\0';
|
||||
return tomoyo_update_domain_keeper_entry(cp + 6, data, is_not,
|
||||
is_delete);
|
||||
char *domainname = strstr(data, " from ");
|
||||
if (domainname) {
|
||||
*domainname = '\0';
|
||||
domainname += 6;
|
||||
} else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP ||
|
||||
type == TOMOYO_TRANSITION_CONTROL_KEEP) {
|
||||
domainname = data;
|
||||
data = NULL;
|
||||
}
|
||||
return tomoyo_update_domain_keeper_entry(data, NULL, is_not, is_delete);
|
||||
return tomoyo_update_transition_control_entry(domainname, data, type,
|
||||
is_delete);
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_domain_keeper - Check whether the given program causes domain transition suppression.
|
||||
* tomoyo_transition_type - Get domain transition type.
|
||||
*
|
||||
* @domainname: The name of domain.
|
||||
* @program: The name of program.
|
||||
* @last_name: The last component of @domainname.
|
||||
*
|
||||
* Returns true if executing @program supresses domain transition,
|
||||
* false otherwise.
|
||||
* Returns TOMOYO_TRANSITION_CONTROL_INITIALIZE if executing @program
|
||||
* reinitializes domain transition, TOMOYO_TRANSITION_CONTROL_KEEP if executing
|
||||
* @program suppresses domain transition, others otherwise.
|
||||
*
|
||||
* Caller holds tomoyo_read_lock().
|
||||
*/
|
||||
static bool tomoyo_domain_keeper(const struct tomoyo_path_info *domainname,
|
||||
const struct tomoyo_path_info *program,
|
||||
const struct tomoyo_path_info *last_name)
|
||||
static u8 tomoyo_transition_type(const struct tomoyo_path_info *domainname,
|
||||
const struct tomoyo_path_info *program)
|
||||
{
|
||||
struct tomoyo_domain_keeper_entry *ptr;
|
||||
bool flag = false;
|
||||
|
||||
list_for_each_entry_rcu(ptr,
|
||||
&tomoyo_policy_list[TOMOYO_ID_DOMAIN_KEEPER],
|
||||
const struct tomoyo_transition_control *ptr;
|
||||
const char *last_name = tomoyo_last_word(domainname->name);
|
||||
u8 type;
|
||||
for (type = 0; type < TOMOYO_MAX_TRANSITION_TYPE; type++) {
|
||||
next:
|
||||
list_for_each_entry_rcu(ptr, &tomoyo_policy_list
|
||||
[TOMOYO_ID_TRANSITION_CONTROL],
|
||||
head.list) {
|
||||
if (ptr->head.is_deleted)
|
||||
if (ptr->head.is_deleted || ptr->type != type)
|
||||
continue;
|
||||
if (ptr->domainname) {
|
||||
if (!ptr->is_last_name) {
|
||||
if (ptr->domainname != domainname)
|
||||
continue;
|
||||
} else {
|
||||
if (tomoyo_pathcmp(ptr->domainname, last_name))
|
||||
/*
|
||||
* Use direct strcmp() since this is
|
||||
* unlikely used.
|
||||
*/
|
||||
if (strcmp(ptr->domainname->name,
|
||||
last_name))
|
||||
continue;
|
||||
}
|
||||
if (ptr->program && tomoyo_pathcmp(ptr->program, program))
|
||||
}
|
||||
if (ptr->program &&
|
||||
tomoyo_pathcmp(ptr->program, program))
|
||||
continue;
|
||||
if (ptr->is_not) {
|
||||
flag = false;
|
||||
break;
|
||||
if (type == TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE) {
|
||||
/*
|
||||
* Do not check for initialize_domain if
|
||||
* no_initialize_domain matched.
|
||||
*/
|
||||
type = TOMOYO_TRANSITION_CONTROL_NO_KEEP;
|
||||
goto next;
|
||||
}
|
||||
flag = true;
|
||||
goto done;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
done:
|
||||
return type;
|
||||
}
|
||||
|
||||
static bool tomoyo_same_aggregator_entry(const struct tomoyo_acl_head *a,
|
||||
|
@ -533,7 +424,6 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
|
|||
char *tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
|
||||
struct tomoyo_domain_info *old_domain = tomoyo_domain();
|
||||
struct tomoyo_domain_info *domain = NULL;
|
||||
const char *old_domain_name = old_domain->domainname->name;
|
||||
const char *original_name = bprm->filename;
|
||||
u8 mode;
|
||||
bool is_enforce;
|
||||
|
@ -586,25 +476,33 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
|
|||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
if (tomoyo_domain_initializer(old_domain->domainname, &rn, &ln)) {
|
||||
/* Calculate domain to transit to. */
|
||||
switch (tomoyo_transition_type(old_domain->domainname, &rn)) {
|
||||
case TOMOYO_TRANSITION_CONTROL_INITIALIZE:
|
||||
/* Transit to the child of tomoyo_kernel_domain domain. */
|
||||
snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1,
|
||||
TOMOYO_ROOT_NAME " " "%s", rn.name);
|
||||
} else if (old_domain == &tomoyo_kernel_domain &&
|
||||
snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, TOMOYO_ROOT_NAME " "
|
||||
"%s", rn.name);
|
||||
break;
|
||||
case TOMOYO_TRANSITION_CONTROL_KEEP:
|
||||
/* Keep current domain. */
|
||||
domain = old_domain;
|
||||
break;
|
||||
default:
|
||||
if (old_domain == &tomoyo_kernel_domain &&
|
||||
!tomoyo_policy_loaded) {
|
||||
/*
|
||||
* Needn't to transit from kernel domain before starting
|
||||
* /sbin/init. But transit from kernel domain if executing
|
||||
* initializers because they might start before /sbin/init.
|
||||
* Needn't to transit from kernel domain before
|
||||
* starting /sbin/init. But transit from kernel domain
|
||||
* if executing initializers because they might start
|
||||
* before /sbin/init.
|
||||
*/
|
||||
domain = old_domain;
|
||||
} else if (tomoyo_domain_keeper(old_domain->domainname, &rn, &ln)) {
|
||||
/* Keep current domain. */
|
||||
domain = old_domain;
|
||||
} else {
|
||||
/* Normal domain transition. */
|
||||
snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1,
|
||||
"%s %s", old_domain_name, rn.name);
|
||||
snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
|
||||
old_domain->domainname->name, rn.name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (domain || strlen(tmp) >= TOMOYO_EXEC_TMPSIZE - 10)
|
||||
goto done;
|
||||
|
|
|
@ -53,17 +53,9 @@ static void tomoyo_del_no_rewrite(struct list_head *element)
|
|||
tomoyo_put_name(ptr->pattern);
|
||||
}
|
||||
|
||||
static void tomoyo_del_domain_initializer(struct list_head *element)
|
||||
static void tomoyo_del_transition_control(struct list_head *element)
|
||||
{
|
||||
struct tomoyo_domain_initializer_entry *ptr =
|
||||
container_of(element, typeof(*ptr), head.list);
|
||||
tomoyo_put_name(ptr->domainname);
|
||||
tomoyo_put_name(ptr->program);
|
||||
}
|
||||
|
||||
static void tomoyo_del_domain_keeper(struct list_head *element)
|
||||
{
|
||||
struct tomoyo_domain_keeper_entry *ptr =
|
||||
struct tomoyo_transition_control *ptr =
|
||||
container_of(element, typeof(*ptr), head.list);
|
||||
tomoyo_put_name(ptr->domainname);
|
||||
tomoyo_put_name(ptr->program);
|
||||
|
@ -292,11 +284,8 @@ static void tomoyo_kfree_entry(void)
|
|||
list_for_each_entry_safe(p, tmp, &tomoyo_gc_queue, list) {
|
||||
struct list_head *element = p->element;
|
||||
switch (p->type) {
|
||||
case TOMOYO_ID_DOMAIN_INITIALIZER:
|
||||
tomoyo_del_domain_initializer(element);
|
||||
break;
|
||||
case TOMOYO_ID_DOMAIN_KEEPER:
|
||||
tomoyo_del_domain_keeper(element);
|
||||
case TOMOYO_ID_TRANSITION_CONTROL:
|
||||
tomoyo_del_transition_control(element);
|
||||
break;
|
||||
case TOMOYO_ID_AGGREGATOR:
|
||||
tomoyo_del_aggregator(element);
|
||||
|
|
|
@ -211,10 +211,10 @@ void __init tomoyo_mm_init(void)
|
|||
panic("Can't register tomoyo_kernel_domain");
|
||||
{
|
||||
/* Load built-in policy. */
|
||||
tomoyo_write_domain_initializer_policy("/sbin/hotplug",
|
||||
false, false);
|
||||
tomoyo_write_domain_initializer_policy("/sbin/modprobe",
|
||||
false, false);
|
||||
tomoyo_write_transition_control("/sbin/hotplug", false,
|
||||
TOMOYO_TRANSITION_CONTROL_INITIALIZE);
|
||||
tomoyo_write_transition_control("/sbin/modprobe", false,
|
||||
TOMOYO_TRANSITION_CONTROL_INITIALIZE);
|
||||
}
|
||||
tomoyo_read_unlock(idx);
|
||||
}
|
||||
|
|
|
@ -844,7 +844,7 @@ int tomoyo_init_request_info(struct tomoyo_request_info *r,
|
|||
*
|
||||
* Returns the last word of a line.
|
||||
*/
|
||||
static const char *tomoyo_last_word(const char *name)
|
||||
const char *tomoyo_last_word(const char *name)
|
||||
{
|
||||
const char *cp = strrchr(name, ' ');
|
||||
if (cp)
|
||||
|
|
Loading…
Reference in New Issue