Skip to content

Commit

Permalink
TOMOYO: Cleanup part 1.
Browse files Browse the repository at this point in the history
In order to synchronize with TOMOYO 1.8's syntax,

(1) Remove special handling for allow_read/write permission.
(2) Replace deny_rewrite/allow_rewrite permission with allow_append permission.
(3) Remove file_pattern keyword.
(4) Remove allow_read permission from exception policy.
(5) Allow creating domains in enforcing mode without calling supervisor.
(6) Add permission check for opening directory for reading.
(7) Add permission check for stat() operation.
(8) Make "cat < /sys/kernel/security/tomoyo/self_domain" behave as if
    "cat /sys/kernel/security/tomoyo/self_domain".

Signed-off-by: Tetsuo Handa <[email protected]>
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
Tetsuo Handa authored and James Morris committed Jun 28, 2011
1 parent 1252cc3 commit 7c75964
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 535 deletions.
60 changes: 4 additions & 56 deletions security/tomoyo/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ static const char *tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
[TOMOYO_MAC_FILE_OPEN] = "file::open",
[TOMOYO_MAC_FILE_CREATE] = "file::create",
[TOMOYO_MAC_FILE_UNLINK] = "file::unlink",
[TOMOYO_MAC_FILE_GETATTR] = "file::getattr",
[TOMOYO_MAC_FILE_MKDIR] = "file::mkdir",
[TOMOYO_MAC_FILE_RMDIR] = "file::rmdir",
[TOMOYO_MAC_FILE_MKFIFO] = "file::mkfifo",
[TOMOYO_MAC_FILE_MKSOCK] = "file::mksock",
[TOMOYO_MAC_FILE_TRUNCATE] = "file::truncate",
[TOMOYO_MAC_FILE_SYMLINK] = "file::symlink",
[TOMOYO_MAC_FILE_REWRITE] = "file::rewrite",
[TOMOYO_MAC_FILE_MKBLOCK] = "file::mkblock",
[TOMOYO_MAC_FILE_MKCHAR] = "file::mkchar",
[TOMOYO_MAC_FILE_LINK] = "file::link",
Expand Down Expand Up @@ -881,10 +881,6 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
domain->profile = (u8) profile;
return 0;
}
if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
domain->ignore_global_allow_read = !is_delete;
return 0;
}
if (!strcmp(data, TOMOYO_KEYWORD_QUOTA_EXCEEDED)) {
domain->quota_warned = !is_delete;
return 0;
Expand Down Expand Up @@ -942,11 +938,6 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
if (head->r.print_execute_only &&
bit != TOMOYO_TYPE_EXECUTE)
continue;
/* Print "read/write" instead of "read" and "write". */
if ((bit == TOMOYO_TYPE_READ ||
bit == TOMOYO_TYPE_WRITE)
&& (perm & (1 << TOMOYO_TYPE_READ_WRITE)))
continue;
break;
}
if (bit >= TOMOYO_MAX_PATH_OPERATION)
Expand Down Expand Up @@ -1055,10 +1046,6 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
tomoyo_set_string(head, "quota_exceeded\n");
if (domain->transition_failed)
tomoyo_set_string(head, "transition_failed\n");
if (domain->ignore_global_allow_read)
tomoyo_set_string(head,
TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ
"\n");
head->r.step++;
tomoyo_set_lf(head);
/* fall through */
Expand Down Expand Up @@ -1235,18 +1222,15 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
static const struct {
const char *keyword;
int (*write) (char *, const bool);
} tomoyo_callback[4] = {
} tomoyo_callback[1] = {
{ TOMOYO_KEYWORD_AGGREGATOR, tomoyo_write_aggregator },
{ TOMOYO_KEYWORD_FILE_PATTERN, tomoyo_write_pattern },
{ TOMOYO_KEYWORD_DENY_REWRITE, tomoyo_write_no_rewrite },
{ TOMOYO_KEYWORD_ALLOW_READ, tomoyo_write_globally_readable },
};

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);
for (i = 0; i < 4; i++)
for (i = 0; i < 1; i++)
if (tomoyo_str_starts(&data, tomoyo_callback[i].keyword))
return tomoyo_callback[i].write(data, is_delete);
for (i = 0; i < TOMOYO_MAX_GROUP; i++)
Expand Down Expand Up @@ -1336,15 +1320,6 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
name);
}
break;
case TOMOYO_ID_GLOBALLY_READABLE:
{
struct tomoyo_readable_file *ptr =
container_of(acl, typeof(*ptr), head);
tomoyo_set_string(head,
TOMOYO_KEYWORD_ALLOW_READ);
tomoyo_set_string(head, ptr->filename->name);
}
break;
case TOMOYO_ID_AGGREGATOR:
{
struct tomoyo_aggregator *ptr =
Expand All @@ -1358,24 +1333,6 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
ptr->aggregated_name->name);
}
break;
case TOMOYO_ID_PATTERN:
{
struct tomoyo_no_pattern *ptr =
container_of(acl, typeof(*ptr), head);
tomoyo_set_string(head,
TOMOYO_KEYWORD_FILE_PATTERN);
tomoyo_set_string(head, ptr->pattern->name);
}
break;
case TOMOYO_ID_NO_REWRITE:
{
struct tomoyo_no_rewrite *ptr =
container_of(acl, typeof(*ptr), head);
tomoyo_set_string(head,
TOMOYO_KEYWORD_DENY_REWRITE);
tomoyo_set_string(head, ptr->pattern->name);
}
break;
default:
continue;
}
Expand Down Expand Up @@ -1890,22 +1847,13 @@ int tomoyo_open_control(const u8 type, struct file *file)
if (type != TOMOYO_QUERY)
head->reader_idx = tomoyo_read_lock();
file->private_data = head;
/*
* Call the handler now if the file is
* /sys/kernel/security/tomoyo/self_domain
* so that the user can use
* cat < /sys/kernel/security/tomoyo/self_domain"
* to know the current process's domainname.
*/
if (type == TOMOYO_SELFDOMAIN)
tomoyo_read_control(file, NULL, 0);
/*
* If the file is /sys/kernel/security/tomoyo/query , increment the
* observer counter.
* The obserber counter is used by tomoyo_supervisor() to see if
* there is some process monitoring /sys/kernel/security/tomoyo/query.
*/
else if (type == TOMOYO_QUERY)
if (type == TOMOYO_QUERY)
atomic_inc(&tomoyo_query_observers);
return 0;
}
Expand Down
93 changes: 10 additions & 83 deletions security/tomoyo/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ enum tomoyo_policy_id {
TOMOYO_ID_NUMBER_GROUP,
TOMOYO_ID_TRANSITION_CONTROL,
TOMOYO_ID_AGGREGATOR,
TOMOYO_ID_GLOBALLY_READABLE,
TOMOYO_ID_PATTERN,
TOMOYO_ID_NO_REWRITE,
TOMOYO_ID_MANAGER,
TOMOYO_ID_NAME,
TOMOYO_ID_ACL,
Expand All @@ -73,8 +70,6 @@ enum tomoyo_group_id {
#define TOMOYO_KEYWORD_ALLOW_MOUNT "allow_mount "
#define TOMOYO_KEYWORD_ALLOW_READ "allow_read "
#define TOMOYO_KEYWORD_DELETE "delete "
#define TOMOYO_KEYWORD_DENY_REWRITE "deny_rewrite "
#define TOMOYO_KEYWORD_FILE_PATTERN "file_pattern "
#define TOMOYO_KEYWORD_INITIALIZE_DOMAIN "initialize_domain "
#define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain "
#define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
Expand All @@ -83,7 +78,6 @@ enum tomoyo_group_id {
#define TOMOYO_KEYWORD_NUMBER_GROUP "number_group "
#define TOMOYO_KEYWORD_SELECT "select "
#define TOMOYO_KEYWORD_USE_PROFILE "use_profile "
#define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
#define TOMOYO_KEYWORD_QUOTA_EXCEEDED "quota_exceeded"
#define TOMOYO_KEYWORD_TRANSITION_FAILED "transition_failed"
/* A domain definition starts with <kernel>. */
Expand Down Expand Up @@ -115,35 +109,21 @@ enum tomoyo_acl_entry_type_index {
};

/* Index numbers for File Controls. */

/*
* TOMOYO_TYPE_READ_WRITE is special. TOMOYO_TYPE_READ_WRITE is automatically
* set if both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are set.
* Both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are automatically set if
* TOMOYO_TYPE_READ_WRITE is set.
* TOMOYO_TYPE_READ_WRITE is automatically cleared if either TOMOYO_TYPE_READ
* or TOMOYO_TYPE_WRITE is cleared.
* Both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are automatically cleared if
* TOMOYO_TYPE_READ_WRITE is cleared.
*/

enum tomoyo_path_acl_index {
TOMOYO_TYPE_READ_WRITE,
TOMOYO_TYPE_EXECUTE,
TOMOYO_TYPE_READ,
TOMOYO_TYPE_WRITE,
TOMOYO_TYPE_APPEND,
TOMOYO_TYPE_UNLINK,
TOMOYO_TYPE_GETATTR,
TOMOYO_TYPE_RMDIR,
TOMOYO_TYPE_TRUNCATE,
TOMOYO_TYPE_SYMLINK,
TOMOYO_TYPE_REWRITE,
TOMOYO_TYPE_CHROOT,
TOMOYO_TYPE_UMOUNT,
TOMOYO_MAX_PATH_OPERATION
};

#define TOMOYO_RW_MASK ((1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE))

enum tomoyo_mkdev_acl_index {
TOMOYO_TYPE_MKBLOCK,
TOMOYO_TYPE_MKCHAR,
Expand Down Expand Up @@ -187,13 +167,13 @@ enum tomoyo_mac_index {
TOMOYO_MAC_FILE_OPEN,
TOMOYO_MAC_FILE_CREATE,
TOMOYO_MAC_FILE_UNLINK,
TOMOYO_MAC_FILE_GETATTR,
TOMOYO_MAC_FILE_MKDIR,
TOMOYO_MAC_FILE_RMDIR,
TOMOYO_MAC_FILE_MKFIFO,
TOMOYO_MAC_FILE_MKSOCK,
TOMOYO_MAC_FILE_TRUNCATE,
TOMOYO_MAC_FILE_SYMLINK,
TOMOYO_MAC_FILE_REWRITE,
TOMOYO_MAC_FILE_MKBLOCK,
TOMOYO_MAC_FILE_MKCHAR,
TOMOYO_MAC_FILE_LINK,
Expand Down Expand Up @@ -388,9 +368,7 @@ struct tomoyo_acl_info {
* "deleted", false otherwise.
* (6) "quota_warned" is a bool which is used for suppressing warning message
* when learning mode learned too much entries.
* (7) "ignore_global_allow_read" is a bool which is true if this domain
* should ignore "allow_read" directive in exception policy.
* (8) "transition_failed" is a bool which is set to true when this domain was
* (7) "transition_failed" is a bool which is set to true when this domain was
* unable to create a new domain at tomoyo_find_next_domain() because the
* name of the domain to be created was too long or it could not allocate
* memory. If set to true, more than one process continued execve()
Expand All @@ -415,7 +393,6 @@ struct tomoyo_domain_info {
u8 profile; /* Profile number to use. */
bool is_deleted; /* Delete flag. */
bool quota_warned; /* Quota warnning flag. */
bool ignore_global_allow_read; /* Ignore "allow_read" flag. */
bool transition_failed; /* Domain transition failed flag. */
atomic_t users; /* Number of referring credentials. */
};
Expand All @@ -429,10 +406,9 @@ struct tomoyo_domain_info {
* (2) "perm" which is a bitmask of permitted operations.
* (3) "name" is the pathname.
*
* Directives held by this structure are "allow_read/write", "allow_execute",
* "allow_read", "allow_write", "allow_unlink", "allow_rmdir",
* "allow_truncate", "allow_symlink", "allow_rewrite", "allow_chroot" and
* "allow_unmount".
* Directives held by this structure are "allow_execute", "allow_read",
* "allow_write", "allow_append", "allow_unlink", "allow_rmdir",
* "allow_truncate", "allow_symlink", "allow_chroot" and "allow_unmount".
*/
struct tomoyo_path_acl {
struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */
Expand Down Expand Up @@ -573,47 +549,6 @@ struct tomoyo_io_buffer {
u8 type;
};

/*
* tomoyo_readable_file is a structure which is used for holding
* "allow_read" entries.
* It has following fields.
*
* (1) "head" is "struct tomoyo_acl_head".
* (2) "filename" is a pathname which is allowed to open(O_RDONLY).
*/
struct tomoyo_readable_file {
struct tomoyo_acl_head head;
const struct tomoyo_path_info *filename;
};

/*
* tomoyo_no_pattern is a structure which is used for holding
* "file_pattern" entries.
* It has following fields.
*
* (1) "head" is "struct tomoyo_acl_head".
* (2) "pattern" is a pathname pattern which is used for converting pathnames
* to pathname patterns during learning mode.
*/
struct tomoyo_no_pattern {
struct tomoyo_acl_head head;
const struct tomoyo_path_info *pattern;
};

/*
* tomoyo_no_rewrite is a structure which is used for holding
* "deny_rewrite" entries.
* It has following fields.
*
* (1) "head" is "struct tomoyo_acl_head".
* (2) "pattern" is a pathname which is by default not permitted to modify
* already existing content.
*/
struct tomoyo_no_rewrite {
struct tomoyo_acl_head head;
const struct tomoyo_path_info *pattern;
};

/*
* tomoyo_transition_control is a structure which is used for holding
* "initialize_domain"/"no_initialize_domain"/"keep_domain"/"no_keep_domain"
Expand Down Expand Up @@ -764,23 +699,17 @@ int tomoyo_write_aggregator(char *data, 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",
* Create "allow_execute", "allow_read", "allow_write", "allow_append",
* "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir",
* "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar",
* "allow_truncate", "allow_symlink", "allow_rewrite", "allow_rename" and
* "allow_link" entry in domain policy.
* "allow_truncate", "allow_symlink", "allow_rename" and "allow_link" entry
* in domain policy.
*/
int tomoyo_write_file(char *data, struct tomoyo_domain_info *domain,
const bool is_delete);
/* Create "allow_read" entry in exception policy. */
int tomoyo_write_globally_readable(char *data, const bool is_delete);
/* Create "allow_mount" entry in domain policy. */
int tomoyo_write_mount(char *data, struct tomoyo_domain_info *domain,
const bool is_delete);
/* Create "deny_rewrite" entry in exception policy. */
int tomoyo_write_no_rewrite(char *data, const bool is_delete);
/* Create "file_pattern" entry in exception policy. */
int tomoyo_write_pattern(char *data, const bool is_delete);
/* Create "path_group"/"number_group" entry in exception policy. */
int tomoyo_write_group(char *data, const bool is_delete, const u8 type);
int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
Expand Down Expand Up @@ -819,8 +748,6 @@ char *tomoyo_realpath_nofollow(const char *pathname);
* ignores chroot'ed root and the pathname is already solved.
*/
char *tomoyo_realpath_from_path(struct path *path);
/* Get patterned pathname. */
const char *tomoyo_pattern(const struct tomoyo_path_info *filename);

/* Check memory quota. */
bool tomoyo_memory_ok(void *ptr);
Expand Down
13 changes: 2 additions & 11 deletions security/tomoyo/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,17 +510,8 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
if (domain || strlen(tmp) >= TOMOYO_EXEC_TMPSIZE - 10)
goto done;
domain = tomoyo_find_domain(tmp);
if (domain)
goto done;
if (is_enforce) {
int error = tomoyo_supervisor(&r, "# wants to create domain\n"
"%s\n", tmp);
if (error == TOMOYO_RETRY_REQUEST)
goto retry;
if (error < 0)
goto done;
}
domain = tomoyo_assign_domain(tmp, old_domain->profile);
if (!domain)
domain = tomoyo_assign_domain(tmp, old_domain->profile);
done:
if (domain)
goto out;
Expand Down
Loading

0 comments on commit 7c75964

Please sign in to comment.