提交 c3fa109a 编写于 作者: T Tetsuo Handa 提交者: James Morris

TOMOYO: Add description of lists and structures.

This patch adds some descriptions of lists and structures.
This patch contains no code changes.
Signed-off-by: NTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: NJames Morris <jmorris@namei.org>
上级 5bf1692f
...@@ -28,7 +28,13 @@ static const char *tomoyo_mode_2[4] = { ...@@ -28,7 +28,13 @@ static const char *tomoyo_mode_2[4] = {
"disabled", "enabled", "enabled", "enabled" "disabled", "enabled", "enabled", "enabled"
}; };
/* Table for profile. */ /*
* tomoyo_control_array is a static data which contains
*
* (1) functionality name used by /sys/kernel/security/tomoyo/profile .
* (2) initial values for "struct tomoyo_profile".
* (3) max values for "struct tomoyo_profile".
*/
static struct { static struct {
const char *keyword; const char *keyword;
unsigned int current_value; unsigned int current_value;
...@@ -39,7 +45,13 @@ static struct { ...@@ -39,7 +45,13 @@ static struct {
[TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 }, [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 },
}; };
/* Profile table. Memory is allocated as needed. */ /*
* tomoyo_profile is a structure which is used for holding the mode of access
* controls. TOMOYO has 4 modes: disabled, learning, permissive, enforcing.
* An administrator can define up to 256 profiles.
* The ->profile of "struct tomoyo_domain_info" is used for remembering
* the profile's number (0 - 255) assigned to that domain.
*/
static struct tomoyo_profile { static struct tomoyo_profile {
unsigned int value[TOMOYO_MAX_CONTROL_INDEX]; unsigned int value[TOMOYO_MAX_CONTROL_INDEX];
const struct tomoyo_path_info *comment; const struct tomoyo_path_info *comment;
...@@ -1006,7 +1018,19 @@ static int tomoyo_read_profile(struct tomoyo_io_buffer *head) ...@@ -1006,7 +1018,19 @@ static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
return 0; return 0;
} }
/* Structure for policy manager. */ /*
* tomoyo_policy_manager_entry is a structure which is used for holding list of
* domainnames or programs which are permitted to modify configuration via
* /sys/kernel/security/tomoyo/ interface.
* It has following fields.
*
* (1) "list" which is linked to tomoyo_policy_manager_list .
* (2) "manager" is a domainname or a program's pathname.
* (3) "is_domain" is a bool which is true if "manager" is a domainname, false
* otherwise.
* (4) "is_deleted" is a bool which is true if marked as deleted, false
* otherwise.
*/
struct tomoyo_policy_manager_entry { struct tomoyo_policy_manager_entry {
struct list_head list; struct list_head list;
/* A path to program or a domainname. */ /* A path to program or a domainname. */
...@@ -1015,7 +1039,36 @@ struct tomoyo_policy_manager_entry { ...@@ -1015,7 +1039,36 @@ struct tomoyo_policy_manager_entry {
bool is_deleted; /* True if this entry is deleted. */ bool is_deleted; /* True if this entry is deleted. */
}; };
/* The list for "struct tomoyo_policy_manager_entry". */ /*
* tomoyo_policy_manager_list is used for holding list of domainnames or
* programs which are permitted to modify configuration via
* /sys/kernel/security/tomoyo/ interface.
*
* An entry is added by
*
* # echo '<kernel> /sbin/mingetty /bin/login /bin/bash' > \
* /sys/kernel/security/tomoyo/manager
* (if you want to specify by a domainname)
*
* or
*
* # echo '/usr/lib/ccs/editpolicy' > /sys/kernel/security/tomoyo/manager
* (if you want to specify by a program's location)
*
* and is deleted by
*
* # echo 'delete <kernel> /sbin/mingetty /bin/login /bin/bash' > \
* /sys/kernel/security/tomoyo/manager
*
* or
*
* # echo 'delete /usr/lib/ccs/editpolicy' > \
* /sys/kernel/security/tomoyo/manager
*
* and all entries are retrieved by
*
* # cat /sys/kernel/security/tomoyo/manager
*/
static LIST_HEAD(tomoyo_policy_manager_list); static LIST_HEAD(tomoyo_policy_manager_list);
static DECLARE_RWSEM(tomoyo_policy_manager_list_lock); static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
...@@ -2124,7 +2177,13 @@ static ssize_t tomoyo_write(struct file *file, const char __user *buf, ...@@ -2124,7 +2177,13 @@ static ssize_t tomoyo_write(struct file *file, const char __user *buf,
return tomoyo_write_control(file, buf, count); return tomoyo_write_control(file, buf, count);
} }
/* Operations for /sys/kernel/security/tomoyo/ interface. */ /*
* tomoyo_operations is a "struct file_operations" which is used for handling
* /sys/kernel/security/tomoyo/ interface.
*
* Some files under /sys/kernel/security/tomoyo/ directory accept open(O_RDWR).
* See tomoyo_io_buffer for internals.
*/
static const struct file_operations tomoyo_operations = { static const struct file_operations tomoyo_operations = {
.open = tomoyo_open, .open = tomoyo_open,
.release = tomoyo_release, .release = tomoyo_release,
......
...@@ -26,12 +26,40 @@ ...@@ -26,12 +26,40 @@
struct dentry; struct dentry;
struct vfsmount; struct vfsmount;
/* Temporary buffer for holding pathnames. */ /*
* tomoyo_page_buffer is a structure which is used for holding a pathname
* obtained from "struct dentry" and "struct vfsmount" pair.
* As of now, it is 4096 bytes. If users complain that 4096 bytes is too small
* (because TOMOYO escapes non ASCII printable characters using \ooo format),
* we will make the buffer larger.
*/
struct tomoyo_page_buffer { struct tomoyo_page_buffer {
char buffer[4096]; char buffer[4096];
}; };
/* Structure for holding a token. */ /*
* tomoyo_path_info is a structure which is used for holding a string data
* used by TOMOYO.
* This structure has several fields for supporting pattern matching.
*
* (1) "name" is the '\0' terminated string data.
* (2) "hash" is full_name_hash(name, strlen(name)).
* This allows tomoyo_pathcmp() to compare by hash before actually compare
* using strcmp().
* (3) "const_len" is the length of the initial segment of "name" which
* consists entirely of non wildcard characters. In other words, the length
* which we can compare two strings using strncmp().
* (4) "is_dir" is a bool which is true if "name" ends with "/",
* false otherwise.
* TOMOYO distinguishes directory and non-directory. A directory ends with
* "/" and non-directory does not end with "/".
* (5) "is_patterned" is a bool which is true if "name" contains wildcard
* characters, false otherwise. This allows TOMOYO to use "hash" and
* strcmp() for string comparison if "is_patterned" is false.
* (6) "depth" is calculated using the number of "/" characters in "name".
* This allows TOMOYO to avoid comparing two pathnames which never match
* (e.g. whether "/var/www/html/index.html" matches "/tmp/sh-thd-\$").
*/
struct tomoyo_path_info { struct tomoyo_path_info {
const char *name; const char *name;
u32 hash; /* = full_name_hash(name, strlen(name)) */ u32 hash; /* = full_name_hash(name, strlen(name)) */
...@@ -50,7 +78,20 @@ struct tomoyo_path_info { ...@@ -50,7 +78,20 @@ struct tomoyo_path_info {
*/ */
#define TOMOYO_MAX_PATHNAME_LEN 4000 #define TOMOYO_MAX_PATHNAME_LEN 4000
/* Structure for holding requested pathname. */ /*
* tomoyo_path_info_with_data is a structure which is used for holding a
* pathname obtained from "struct dentry" and "struct vfsmount" pair.
*
* "struct tomoyo_path_info_with_data" consists of "struct tomoyo_path_info"
* and buffer for the pathname, while "struct tomoyo_page_buffer" consists of
* buffer for the pathname only.
*
* "struct tomoyo_path_info_with_data" is intended to allow TOMOYO to release
* both "struct tomoyo_path_info" and buffer for the pathname by single kfree()
* so that we don't need to return two pointers to the caller. If the caller
* puts "struct tomoyo_path_info" on stack memory, we will be able to remove
* "struct tomoyo_path_info_with_data".
*/
struct tomoyo_path_info_with_data { struct tomoyo_path_info_with_data {
/* Keep "head" first, for this pointer is passed to tomoyo_free(). */ /* Keep "head" first, for this pointer is passed to tomoyo_free(). */
struct tomoyo_path_info head; struct tomoyo_path_info head;
...@@ -60,7 +101,15 @@ struct tomoyo_path_info_with_data { ...@@ -60,7 +101,15 @@ struct tomoyo_path_info_with_data {
}; };
/* /*
* Common header for holding ACL entries. * tomoyo_acl_info is a structure which is used for holding
*
* (1) "list" which is linked to the ->acl_info_list of
* "struct tomoyo_domain_info"
* (2) "type" which tells
* (a) type & 0x7F : type of the entry (either
* "struct tomoyo_single_path_acl_record" or
* "struct tomoyo_double_path_acl_record")
* (b) type & 0x80 : whether the entry is marked as "deleted".
* *
* Packing "struct tomoyo_acl_info" allows * Packing "struct tomoyo_acl_info" allows
* "struct tomoyo_single_path_acl_record" to embed "u16" and * "struct tomoyo_single_path_acl_record" to embed "u16" and
...@@ -80,7 +129,28 @@ struct tomoyo_acl_info { ...@@ -80,7 +129,28 @@ struct tomoyo_acl_info {
/* This ACL entry is deleted. */ /* This ACL entry is deleted. */
#define TOMOYO_ACL_DELETED 0x80 #define TOMOYO_ACL_DELETED 0x80
/* Structure for domain information. */ /*
* tomoyo_domain_info is a structure which is used for holding permissions
* (e.g. "allow_read /lib/libc-2.5.so") given to each domain.
* It has following fields.
*
* (1) "list" which is linked to tomoyo_domain_list .
* (2) "acl_info_list" which is linked to "struct tomoyo_acl_info".
* (3) "domainname" which holds the name of the domain.
* (4) "profile" which remembers profile number assigned to this domain.
* (5) "is_deleted" is a bool which is true if this domain is marked as
* "deleted", false otherwise.
* (6) "quota_warned" is a bool which is used for suppressing warning message
* when learning mode learned too much entries.
* (7) "flags" which remembers this domain's attributes.
*
* A domain's lifecycle is an analogy of files on / directory.
* Multiple domains with the same domainname cannot be created (as with
* creating files with the same filename fails with -EEXIST).
* If a process reached a domain, that process can reside in that domain after
* that domain is marked as "deleted" (as with a process can access an already
* open()ed file after that file was unlink()ed).
*/
struct tomoyo_domain_info { struct tomoyo_domain_info {
struct list_head list; struct list_head list;
struct list_head acl_info_list; struct list_head acl_info_list;
...@@ -107,10 +177,18 @@ struct tomoyo_domain_info { ...@@ -107,10 +177,18 @@ struct tomoyo_domain_info {
#define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2 #define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2
/* /*
* Structure for "allow_read/write", "allow_execute", "allow_read", * tomoyo_single_path_acl_record is a structure which is used for holding an
* "allow_write", "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir", * entry with one pathname operation (e.g. open(), mkdir()).
* "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar", * It has following fields.
* "allow_truncate", "allow_symlink" and "allow_rewrite" directive. *
* (1) "head" which is a "struct tomoyo_acl_info".
* (2) "perm" which is a bitmask of permitted operations.
* (3) "filename" is the pathname.
*
* Directives held by this structure are "allow_read/write", "allow_execute",
* "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir",
* "allow_rmdir", "allow_mkfifo", "allow_mksock", "allow_mkblock",
* "allow_mkchar", "allow_truncate", "allow_symlink" and "allow_rewrite".
*/ */
struct tomoyo_single_path_acl_record { struct tomoyo_single_path_acl_record {
struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */ struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */
...@@ -119,7 +197,18 @@ struct tomoyo_single_path_acl_record { ...@@ -119,7 +197,18 @@ struct tomoyo_single_path_acl_record {
const struct tomoyo_path_info *filename; const struct tomoyo_path_info *filename;
}; };
/* Structure for "allow_rename" and "allow_link" directive. */ /*
* tomoyo_double_path_acl_record is a structure which is used for holding an
* entry with two pathnames operation (i.e. link() and rename()).
* It has following fields.
*
* (1) "head" which is a "struct tomoyo_acl_info".
* (2) "perm" which is a bitmask of permitted operations.
* (3) "filename1" is the source/old pathname.
* (4) "filename2" is the destination/new pathname.
*
* Directives held by this structure are "allow_rename" and "allow_link".
*/
struct tomoyo_double_path_acl_record { struct tomoyo_double_path_acl_record {
struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */ struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */
u8 perm; u8 perm;
...@@ -152,7 +241,29 @@ struct tomoyo_double_path_acl_record { ...@@ -152,7 +241,29 @@ struct tomoyo_double_path_acl_record {
#define TOMOYO_VERBOSE 2 #define TOMOYO_VERBOSE 2
#define TOMOYO_MAX_CONTROL_INDEX 3 #define TOMOYO_MAX_CONTROL_INDEX 3
/* Structure for reading/writing policy via securityfs interfaces. */ /*
* tomoyo_io_buffer is a structure which is used for reading and modifying
* configuration via /sys/kernel/security/tomoyo/ interface.
* It has many fields. ->read_var1 , ->read_var2 , ->write_var1 are used as
* cursors.
*
* Since the content of /sys/kernel/security/tomoyo/domain_policy is a list of
* "struct tomoyo_domain_info" entries and each "struct tomoyo_domain_info"
* entry has a list of "struct tomoyo_acl_info", we need two cursors when
* reading (one is for traversing tomoyo_domain_list and the other is for
* traversing "struct tomoyo_acl_info"->acl_info_list ).
*
* If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
* "select ", TOMOYO seeks the cursor ->read_var1 and ->write_var1 to the
* domain with the domainname specified by the rest of that line (NULL is set
* if seek failed).
* If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
* "delete ", TOMOYO deletes an entry or a domain specified by the rest of that
* line (->write_var1 is set to NULL if a domain was deleted).
* If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
* neither "select " nor "delete ", an entry or a domain specified by that line
* is appended.
*/
struct tomoyo_io_buffer { struct tomoyo_io_buffer {
int (*read) (struct tomoyo_io_buffer *); int (*read) (struct tomoyo_io_buffer *);
int (*write) (struct tomoyo_io_buffer *); int (*write) (struct tomoyo_io_buffer *);
......
...@@ -19,11 +19,63 @@ ...@@ -19,11 +19,63 @@
/* The initial domain. */ /* The initial domain. */
struct tomoyo_domain_info tomoyo_kernel_domain; struct tomoyo_domain_info tomoyo_kernel_domain;
/* The list for "struct tomoyo_domain_info". */ /*
* tomoyo_domain_list is used for holding list of domains.
* The ->acl_info_list of "struct tomoyo_domain_info" is used for holding
* permissions (e.g. "allow_read /lib/libc-2.5.so") given to each domain.
*
* An entry is added by
*
* # ( echo "<kernel>"; echo "allow_execute /sbin/init" ) > \
* /sys/kernel/security/tomoyo/domain_policy
*
* and is deleted by
*
* # ( echo "<kernel>"; echo "delete allow_execute /sbin/init" ) > \
* /sys/kernel/security/tomoyo/domain_policy
*
* and all entries are retrieved by
*
* # cat /sys/kernel/security/tomoyo/domain_policy
*
* A domain is added by
*
* # echo "<kernel>" > /sys/kernel/security/tomoyo/domain_policy
*
* and is deleted by
*
* # echo "delete <kernel>" > /sys/kernel/security/tomoyo/domain_policy
*
* and all domains are retrieved by
*
* # grep '^<kernel>' /sys/kernel/security/tomoyo/domain_policy
*
* Normally, a domainname is monotonically getting longer because a domainname
* which the process will belong to if an execve() operation succeeds is
* defined as a concatenation of "current domainname" + "pathname passed to
* execve()".
* See tomoyo_domain_initializer_list and tomoyo_domain_keeper_list for
* exceptions.
*/
LIST_HEAD(tomoyo_domain_list); LIST_HEAD(tomoyo_domain_list);
DECLARE_RWSEM(tomoyo_domain_list_lock); DECLARE_RWSEM(tomoyo_domain_list_lock);
/* Structure for "initialize_domain" and "no_initialize_domain" keyword. */ /*
* tomoyo_domain_initializer_entry is a structure which is used for holding
* "initialize_domain" and "no_initialize_domain" entries.
* It has following fields.
*
* (1) "list" which is linked to tomoyo_domain_initializer_list .
* (2) "domainname" which is "a domainname" or "the last component of a
* domainname". This field is NULL if "from" clause is not specified.
* (3) "program" which is a program's pathname.
* (4) "is_deleted" is a bool which is true if marked as deleted, false
* otherwise.
* (5) "is_not" is a bool which is true if "no_initialize_domain", false
* otherwise.
* (6) "is_last_name" is a bool which is true if "domainname" is "the last
* component of a domainname", false otherwise.
*/
struct tomoyo_domain_initializer_entry { struct tomoyo_domain_initializer_entry {
struct list_head list; struct list_head list;
const struct tomoyo_path_info *domainname; /* This may be NULL */ const struct tomoyo_path_info *domainname; /* This may be NULL */
...@@ -34,7 +86,23 @@ struct tomoyo_domain_initializer_entry { ...@@ -34,7 +86,23 @@ struct tomoyo_domain_initializer_entry {
bool is_last_name; bool is_last_name;
}; };
/* Structure for "keep_domain" and "no_keep_domain" keyword. */ /*
* tomoyo_domain_keeper_entry is a structure which is used for holding
* "keep_domain" and "no_keep_domain" entries.
* It has following fields.
*
* (1) "list" which is linked to tomoyo_domain_keeper_list .
* (2) "domainname" which is "a domainname" or "the last component of a
* domainname".
* (3) "program" which is a program's pathname.
* This field is NULL if "from" clause is not specified.
* (4) "is_deleted" is a bool which is true if marked as deleted, false
* otherwise.
* (5) "is_not" is a bool which is true if "no_initialize_domain", false
* otherwise.
* (6) "is_last_name" is a bool which is true if "domainname" is "the last
* component of a domainname", false otherwise.
*/
struct tomoyo_domain_keeper_entry { struct tomoyo_domain_keeper_entry {
struct list_head list; struct list_head list;
const struct tomoyo_path_info *domainname; const struct tomoyo_path_info *domainname;
...@@ -45,7 +113,16 @@ struct tomoyo_domain_keeper_entry { ...@@ -45,7 +113,16 @@ struct tomoyo_domain_keeper_entry {
bool is_last_name; bool is_last_name;
}; };
/* Structure for "alias" keyword. */ /*
* tomoyo_alias_entry is a structure which is used for holding "alias" entries.
* It has following fields.
*
* (1) "list" which is linked to tomoyo_alias_list .
* (2) "original_name" which is a dereferenced pathname.
* (3) "aliased_name" which is a symlink's pathname.
* (4) "is_deleted" is a bool which is true if marked as deleted, false
* otherwise.
*/
struct tomoyo_alias_entry { struct tomoyo_alias_entry {
struct list_head list; struct list_head list;
const struct tomoyo_path_info *original_name; const struct tomoyo_path_info *original_name;
...@@ -92,7 +169,42 @@ const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain) ...@@ -92,7 +169,42 @@ const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain)
return cp0; return cp0;
} }
/* The list for "struct tomoyo_domain_initializer_entry". */ /*
* tomoyo_domain_initializer_list is used for holding list of programs which
* triggers reinitialization of domainname. Normally, a domainname is
* monotonically getting longer. But sometimes, we restart daemon programs.
* It would be convenient for us that "a daemon started upon system boot" and
* "the daemon restarted from console" belong to the same domain. Thus, TOMOYO
* provides a way to shorten domainnames.
*
* An entry is added by
*
* # echo 'initialize_domain /usr/sbin/httpd' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and is deleted by
*
* # echo 'delete initialize_domain /usr/sbin/httpd' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and all entries are retrieved by
*
* # grep ^initialize_domain /sys/kernel/security/tomoyo/exception_policy
*
* In the example above, /usr/sbin/httpd will belong to
* "<kernel> /usr/sbin/httpd" domain.
*
* You may specify a domainname using "from" keyword.
* "initialize_domain /usr/sbin/httpd from <kernel> /etc/rc.d/init.d/httpd"
* will cause "/usr/sbin/httpd" executed from "<kernel> /etc/rc.d/init.d/httpd"
* domain to belong to "<kernel> /usr/sbin/httpd" domain.
*
* You may add "no_" prefix to "initialize_domain".
* "initialize_domain /usr/sbin/httpd" and
* "no_initialize_domain /usr/sbin/httpd from <kernel> /etc/rc.d/init.d/httpd"
* will cause "/usr/sbin/httpd" to belong to "<kernel> /usr/sbin/httpd" domain
* unless executed from "<kernel> /etc/rc.d/init.d/httpd" domain.
*/
static LIST_HEAD(tomoyo_domain_initializer_list); static LIST_HEAD(tomoyo_domain_initializer_list);
static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock); static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock);
...@@ -268,7 +380,44 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info * ...@@ -268,7 +380,44 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
return flag; return flag;
} }
/* The list for "struct tomoyo_domain_keeper_entry". */ /*
* tomoyo_domain_keeper_list is used for holding list of domainnames which
* suppresses domain transition. Normally, a domainname is monotonically
* getting longer. But sometimes, we want to suppress domain transition.
* It would be convenient for us that programs executed from a login session
* belong to the same domain. Thus, TOMOYO provides a way to suppress domain
* transition.
*
* An entry is added by
*
* # echo 'keep_domain <kernel> /usr/sbin/sshd /bin/bash' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and is deleted by
*
* # echo 'delete keep_domain <kernel> /usr/sbin/sshd /bin/bash' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and all entries are retrieved by
*
* # grep ^keep_domain /sys/kernel/security/tomoyo/exception_policy
*
* In the example above, any process which belongs to
* "<kernel> /usr/sbin/sshd /bin/bash" domain will remain in that domain,
* unless explicitly specified by "initialize_domain" or "no_keep_domain".
*
* You may specify a program using "from" keyword.
* "keep_domain /bin/pwd from <kernel> /usr/sbin/sshd /bin/bash"
* will cause "/bin/pwd" executed from "<kernel> /usr/sbin/sshd /bin/bash"
* domain to remain in "<kernel> /usr/sbin/sshd /bin/bash" domain.
*
* You may add "no_" prefix to "keep_domain".
* "keep_domain <kernel> /usr/sbin/sshd /bin/bash" and
* "no_keep_domain /usr/bin/passwd from <kernel> /usr/sbin/sshd /bin/bash" will
* cause "/usr/bin/passwd" to belong to
* "<kernel> /usr/sbin/sshd /bin/bash /usr/bin/passwd" domain, unless
* explicitly specified by "initialize_domain".
*/
static LIST_HEAD(tomoyo_domain_keeper_list); static LIST_HEAD(tomoyo_domain_keeper_list);
static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock); static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock);
...@@ -437,7 +586,36 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname, ...@@ -437,7 +586,36 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
return flag; return flag;
} }
/* The list for "struct tomoyo_alias_entry". */ /*
* tomoyo_alias_list is used for holding list of symlink's pathnames which are
* allowed to be passed to an execve() request. Normally, the domainname which
* the current process will belong to after execve() succeeds is calculated
* using dereferenced pathnames. But some programs behave differently depending
* on the name passed to argv[0]. For busybox, calculating domainname using
* dereferenced pathnames will cause all programs in the busybox to belong to
* the same domain. Thus, TOMOYO provides a way to allow use of symlink's
* pathname for checking execve()'s permission and calculating domainname which
* the current process will belong to after execve() succeeds.
*
* An entry is added by
*
* # echo 'alias /bin/busybox /bin/cat' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and is deleted by
*
* # echo 'delete alias /bin/busybox /bin/cat' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and all entries are retrieved by
*
* # grep ^alias /sys/kernel/security/tomoyo/exception_policy
*
* In the example above, if /bin/cat is a symlink to /bin/busybox and execution
* of /bin/cat is requested, permission is checked for /bin/cat rather than
* /bin/busybox and domainname which the current process will belong to after
* execve() succeeds is calculated using /bin/cat rather than /bin/busybox .
*/
static LIST_HEAD(tomoyo_alias_list); static LIST_HEAD(tomoyo_alias_list);
static DECLARE_RWSEM(tomoyo_alias_list_lock); static DECLARE_RWSEM(tomoyo_alias_list_lock);
......
...@@ -14,21 +14,50 @@ ...@@ -14,21 +14,50 @@
#include "realpath.h" #include "realpath.h"
#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
/* Structure for "allow_read" keyword. */ /*
* tomoyo_globally_readable_file_entry is a structure which is used for holding
* "allow_read" entries.
* It has following fields.
*
* (1) "list" which is linked to tomoyo_globally_readable_list .
* (2) "filename" is a pathname which is allowed to open(O_RDONLY).
* (3) "is_deleted" is a bool which is true if marked as deleted, false
* otherwise.
*/
struct tomoyo_globally_readable_file_entry { struct tomoyo_globally_readable_file_entry {
struct list_head list; struct list_head list;
const struct tomoyo_path_info *filename; const struct tomoyo_path_info *filename;
bool is_deleted; bool is_deleted;
}; };
/* Structure for "file_pattern" keyword. */ /*
* tomoyo_pattern_entry is a structure which is used for holding
* "tomoyo_pattern_list" entries.
* It has following fields.
*
* (1) "list" which is linked to tomoyo_pattern_list .
* (2) "pattern" is a pathname pattern which is used for converting pathnames
* to pathname patterns during learning mode.
* (3) "is_deleted" is a bool which is true if marked as deleted, false
* otherwise.
*/
struct tomoyo_pattern_entry { struct tomoyo_pattern_entry {
struct list_head list; struct list_head list;
const struct tomoyo_path_info *pattern; const struct tomoyo_path_info *pattern;
bool is_deleted; bool is_deleted;
}; };
/* Structure for "deny_rewrite" keyword. */ /*
* tomoyo_no_rewrite_entry is a structure which is used for holding
* "deny_rewrite" entries.
* It has following fields.
*
* (1) "list" which is linked to tomoyo_no_rewrite_list .
* (2) "pattern" is a pathname which is by default not permitted to modify
* already existing content.
* (3) "is_deleted" is a bool which is true if marked as deleted, false
* otherwise.
*/
struct tomoyo_no_rewrite_entry { struct tomoyo_no_rewrite_entry {
struct list_head list; struct list_head list;
const struct tomoyo_path_info *pattern; const struct tomoyo_path_info *pattern;
...@@ -141,7 +170,31 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename, ...@@ -141,7 +170,31 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
struct tomoyo_domain_info * struct tomoyo_domain_info *
const domain, const bool is_delete); const domain, const bool is_delete);
/* The list for "struct tomoyo_globally_readable_file_entry". */ /*
* tomoyo_globally_readable_list is used for holding list of pathnames which
* are by default allowed to be open()ed for reading by any process.
*
* An entry is added by
*
* # echo 'allow_read /lib/libc-2.5.so' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and is deleted by
*
* # echo 'delete allow_read /lib/libc-2.5.so' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and all entries are retrieved by
*
* # grep ^allow_read /sys/kernel/security/tomoyo/exception_policy
*
* In the example above, any process is allowed to
* open("/lib/libc-2.5.so", O_RDONLY).
* One exception is, if the domain which current process belongs to is marked
* as "ignore_global_allow_read", current process can't do so unless explicitly
* given "allow_read /lib/libc-2.5.so" to the domain which current process
* belongs to.
*/
static LIST_HEAD(tomoyo_globally_readable_list); static LIST_HEAD(tomoyo_globally_readable_list);
static DECLARE_RWSEM(tomoyo_globally_readable_list_lock); static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);
...@@ -256,7 +309,35 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) ...@@ -256,7 +309,35 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
return done; return done;
} }
/* The list for "struct tomoyo_pattern_entry". */ /* tomoyo_pattern_list is used for holding list of pathnames which are used for
* converting pathnames to pathname patterns during learning mode.
*
* An entry is added by
*
* # echo 'file_pattern /proc/\$/mounts' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and is deleted by
*
* # echo 'delete file_pattern /proc/\$/mounts' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and all entries are retrieved by
*
* # grep ^file_pattern /sys/kernel/security/tomoyo/exception_policy
*
* In the example above, if a process which belongs to a domain which is in
* learning mode requested open("/proc/1/mounts", O_RDONLY),
* "allow_read /proc/\$/mounts" is automatically added to the domain which that
* process belongs to.
*
* It is not a desirable behavior that we have to use /proc/\$/ instead of
* /proc/self/ when current process needs to access only current process's
* information. As of now, LSM version of TOMOYO is using __d_path() for
* calculating pathname. Non LSM version of TOMOYO is using its own function
* which pretends as if /proc/self/ is not a symlink; so that we can forbid
* current process from accessing other process's information.
*/
static LIST_HEAD(tomoyo_pattern_list); static LIST_HEAD(tomoyo_pattern_list);
static DECLARE_RWSEM(tomoyo_pattern_list_lock); static DECLARE_RWSEM(tomoyo_pattern_list_lock);
...@@ -377,7 +458,35 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) ...@@ -377,7 +458,35 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
return done; return done;
} }
/* The list for "struct tomoyo_no_rewrite_entry". */ /*
* tomoyo_no_rewrite_list is used for holding list of pathnames which are by
* default forbidden to modify already written content of a file.
*
* An entry is added by
*
* # echo 'deny_rewrite /var/log/messages' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and is deleted by
*
* # echo 'delete deny_rewrite /var/log/messages' > \
* /sys/kernel/security/tomoyo/exception_policy
*
* and all entries are retrieved by
*
* # grep ^deny_rewrite /sys/kernel/security/tomoyo/exception_policy
*
* In the example above, if a process requested to rewrite /var/log/messages ,
* the process can't rewrite unless the domain which that process belongs to
* has "allow_rewrite /var/log/messages" entry.
*
* It is not a desirable behavior that we have to add "\040(deleted)" suffix
* when we want to allow rewriting already unlink()ed file. As of now,
* LSM version of TOMOYO is using __d_path() for calculating pathname.
* Non LSM version of TOMOYO is using its own function which doesn't append
* " (deleted)" suffix if the file is already unlink()ed; so that we don't
* need to worry whether the file is already unlink()ed or not.
*/
static LIST_HEAD(tomoyo_no_rewrite_list); static LIST_HEAD(tomoyo_no_rewrite_list);
static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock); static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
......
...@@ -265,7 +265,16 @@ static unsigned int tomoyo_quota_for_savename; ...@@ -265,7 +265,16 @@ static unsigned int tomoyo_quota_for_savename;
*/ */
#define TOMOYO_MAX_HASH 256 #define TOMOYO_MAX_HASH 256
/* Structure for string data. */ /*
* tomoyo_name_entry is a structure which is used for linking
* "struct tomoyo_path_info" into tomoyo_name_list .
*
* Since tomoyo_name_list manages a list of strings which are shared by
* multiple processes (whereas "struct tomoyo_path_info" inside
* "struct tomoyo_path_info_with_data" is not shared), a reference counter will
* be added to "struct tomoyo_name_entry" rather than "struct tomoyo_path_info"
* when TOMOYO starts supporting garbage collector.
*/
struct tomoyo_name_entry { struct tomoyo_name_entry {
struct list_head list; struct list_head list;
struct tomoyo_path_info entry; struct tomoyo_path_info entry;
...@@ -279,10 +288,10 @@ struct tomoyo_free_memory_block_list { ...@@ -279,10 +288,10 @@ struct tomoyo_free_memory_block_list {
}; };
/* /*
* The list for "struct tomoyo_name_entry". * tomoyo_name_list is used for holding string data used by TOMOYO.
* * Since same string data is likely used for multiple times (e.g.
* This list is updated only inside tomoyo_save_name(), thus * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
* no global mutex exists. * "const struct tomoyo_path_info *".
*/ */
static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
......
...@@ -262,6 +262,10 @@ static int tomoyo_dentry_open(struct file *f, const struct cred *cred) ...@@ -262,6 +262,10 @@ static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
} }
/*
* tomoyo_security_ops is a "struct security_operations" which is used for
* registering TOMOYO.
*/
static struct security_operations tomoyo_security_ops = { static struct security_operations tomoyo_security_ops = {
.name = "tomoyo", .name = "tomoyo",
.cred_prepare = tomoyo_cred_prepare, .cred_prepare = tomoyo_cred_prepare,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册