Commit 7c75964f authored by Tetsuo Handa's avatar Tetsuo Handa Committed by James Morris

TOMOYO: Cleanup part 1.

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: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 1252cc3b
......@@ -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",
......@@ -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;
......@@ -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)
......@@ -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 */
......@@ -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++)
......@@ -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 =
......@@ -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;
}
......@@ -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;
}
......
......@@ -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,
......@@ -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 "
......@@ -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>. */
......@@ -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,
......@@ -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,
......@@ -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()
......@@ -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. */
};
......@@ -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 */
......@@ -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"
......@@ -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, ...)
......@@ -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);
......
......@@ -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;
......
This diff is collapsed.
......@@ -32,27 +32,6 @@ static bool tomoyo_add_to_gc(const int type, struct list_head *element)
return true;
}
static void tomoyo_del_allow_read(struct list_head *element)
{
struct tomoyo_readable_file *ptr =
container_of(element, typeof(*ptr), head.list);
tomoyo_put_name(ptr->filename);
}
static void tomoyo_del_file_pattern(struct list_head *element)
{
struct tomoyo_no_pattern *ptr =
container_of(element, typeof(*ptr), head.list);
tomoyo_put_name(ptr->pattern);
}
static void tomoyo_del_no_rewrite(struct list_head *element)
{
struct tomoyo_no_rewrite *ptr =
container_of(element, typeof(*ptr), head.list);
tomoyo_put_name(ptr->pattern);
}
static void tomoyo_del_transition_control(struct list_head *element)
{
struct tomoyo_transition_control *ptr =
......@@ -290,15 +269,6 @@ static void tomoyo_kfree_entry(void)
case TOMOYO_ID_AGGREGATOR:
tomoyo_del_aggregator(element);
break;
case TOMOYO_ID_GLOBALLY_READABLE:
tomoyo_del_allow_read(element);
break;
case TOMOYO_ID_PATTERN:
tomoyo_del_file_pattern(element);
break;
case TOMOYO_ID_NO_REWRITE:
tomoyo_del_no_rewrite(element);
break;
case TOMOYO_ID_MANAGER:
tomoyo_del_manager(element);
break;
......
......@@ -55,9 +55,8 @@ static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
flags);
return tomoyo_supervisor(r,
TOMOYO_KEYWORD_ALLOW_MOUNT "%s %s %s 0x%lX\n",
tomoyo_pattern(r->param.mount.dev),
tomoyo_pattern(r->param.mount.dir), type,
flags);
r->param.mount.dev->name,
r->param.mount.dir->name, type, flags);
}
static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
......
......@@ -93,6 +93,12 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
return tomoyo_check_open_permission(domain, &bprm->file->f_path, O_RDONLY);
}
static int tomoyo_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
{
struct path path = { mnt, dentry };
return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, &path);
}
static int tomoyo_path_truncate(struct path *path)
{
return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path);
......@@ -176,9 +182,10 @@ static int tomoyo_path_rename(struct path *old_parent,
static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
unsigned long arg)
{
if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND))
return tomoyo_path_perm(TOMOYO_TYPE_REWRITE, &file->f_path);
return 0;
if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
return 0;
return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
O_WRONLY | (arg & O_APPEND));
}
static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
......@@ -258,6 +265,7 @@ static struct security_operations tomoyo_security_ops = {
.path_mknod = tomoyo_path_mknod,
.path_link = tomoyo_path_link,
.path_rename = tomoyo_path_rename,
.inode_getattr = tomoyo_inode_getattr,
.file_ioctl = tomoyo_file_ioctl,
.path_chmod = tomoyo_path_chmod,
.path_chown = tomoyo_path_chown,
......
......@@ -911,44 +911,33 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
if (!domain)
return true;
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
u16 perm;
u8 i;
if (ptr->is_deleted)
continue;
switch (ptr->type) {
u16 perm;
u8 i;
case TOMOYO_TYPE_PATH_ACL:
perm = container_of(ptr, struct tomoyo_path_acl, head)
->perm;
for (i = 0; i < TOMOYO_MAX_PATH_OPERATION; i++)
if (perm & (1 << i))
count++;
if (perm & (1 << TOMOYO_TYPE_READ_WRITE))
count -= 2;
break;
case TOMOYO_TYPE_PATH2_ACL:
perm = container_of(ptr, struct tomoyo_path2_acl, head)
->perm;
for (i = 0; i < TOMOYO_MAX_PATH2_OPERATION; i++)
if (perm & (1 << i))
count++;
break;
case TOMOYO_TYPE_PATH_NUMBER_ACL:
perm = container_of(ptr, struct tomoyo_path_number_acl,
head)->perm;
for (i = 0; i < TOMOYO_MAX_PATH_NUMBER_OPERATION; i++)
if (perm & (1 << i))
count++;
break;
case TOMOYO_TYPE_MKDEV_ACL:
perm = container_of(ptr, struct tomoyo_mkdev_acl,
head)->perm;
for (i = 0; i < TOMOYO_MAX_MKDEV_OPERATION; i++)
if (perm & (1 << i))
count++;
break;
default:
count++;
perm = 1;
}
for (i = 0; i < 16; i++)
if (perm & (1 << i))
count++;
}
if (count < tomoyo_profile(domain->profile)->learning->
learning_max_entry)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment