aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-06-26 10:16:36 -0400
committerJames Morris <jmorris@namei.org>2011-06-28 19:31:19 -0400
commit0df7e8b8f1c25c10820bdc679555f2fbfb897ca0 (patch)
tree626a0304fceec0bbee93e43a24bc0f813fe230b7
parentb5bc60b4ce313b6dbb42e7d32915dcf0a07c2a68 (diff)
TOMOYO: Cleanup part 3.
Use common structure for ACL with "struct list_head" + "atomic_t". Use array/struct where possible. Remove is_group from "struct tomoyo_name_union"/"struct tomoyo_number_union". Pass "struct file"->private_data rather than "struct file". Update some of comments. Bring tomoyo_same_acl_head() from common.h to domain.c . Bring tomoyo_invalid()/tomoyo_valid() from common.h to util.c . Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--security/tomoyo/common.c43
-rw-r--r--security/tomoyo/common.h78
-rw-r--r--security/tomoyo/domain.c17
-rw-r--r--security/tomoyo/file.c208
-rw-r--r--security/tomoyo/gc.c127
-rw-r--r--security/tomoyo/memory.c16
-rw-r--r--security/tomoyo/mount.c31
-rw-r--r--security/tomoyo/securityfs_if.c6
-rw-r--r--security/tomoyo/util.c37
9 files changed, 410 insertions, 153 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 1c340217a06a..2e6792ded357 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -192,7 +192,7 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
192 const struct tomoyo_name_union *ptr) 192 const struct tomoyo_name_union *ptr)
193{ 193{
194 tomoyo_set_space(head); 194 tomoyo_set_space(head);
195 if (ptr->is_group) { 195 if (ptr->group) {
196 tomoyo_set_string(head, "@"); 196 tomoyo_set_string(head, "@");
197 tomoyo_set_string(head, ptr->group->group_name->name); 197 tomoyo_set_string(head, ptr->group->group_name->name);
198 } else { 198 } else {
@@ -210,15 +210,15 @@ static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
210 const struct tomoyo_number_union *ptr) 210 const struct tomoyo_number_union *ptr)
211{ 211{
212 tomoyo_set_space(head); 212 tomoyo_set_space(head);
213 if (ptr->is_group) { 213 if (ptr->group) {
214 tomoyo_set_string(head, "@"); 214 tomoyo_set_string(head, "@");
215 tomoyo_set_string(head, ptr->group->group_name->name); 215 tomoyo_set_string(head, ptr->group->group_name->name);
216 } else { 216 } else {
217 int i; 217 int i;
218 unsigned long min = ptr->values[0]; 218 unsigned long min = ptr->values[0];
219 const unsigned long max = ptr->values[1]; 219 const unsigned long max = ptr->values[1];
220 u8 min_type = ptr->min_type; 220 u8 min_type = ptr->value_type[0];
221 const u8 max_type = ptr->max_type; 221 const u8 max_type = ptr->value_type[1];
222 char buffer[128]; 222 char buffer[128];
223 buffer[0] = '\0'; 223 buffer[0] = '\0';
224 for (i = 0; i < 2; i++) { 224 for (i = 0; i < 2; i++) {
@@ -769,7 +769,7 @@ static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data)
769 domain = tomoyo_find_domain(data + 7); 769 domain = tomoyo_find_domain(data + 7);
770 } else 770 } else
771 return false; 771 return false;
772 head->write_var1 = domain; 772 head->w.domain = domain;
773 /* Accessing read_buf is safe because head->io_sem is held. */ 773 /* Accessing read_buf is safe because head->io_sem is held. */
774 if (!head->read_buf) 774 if (!head->read_buf)
775 return true; /* Do nothing if open(O_WRONLY). */ 775 return true; /* Do nothing if open(O_WRONLY). */
@@ -847,7 +847,7 @@ static int tomoyo_write_domain2(char *data, struct tomoyo_domain_info *domain,
847static int tomoyo_write_domain(struct tomoyo_io_buffer *head) 847static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
848{ 848{
849 char *data = head->write_buf; 849 char *data = head->write_buf;
850 struct tomoyo_domain_info *domain = head->write_var1; 850 struct tomoyo_domain_info *domain = head->w.domain;
851 bool is_delete = false; 851 bool is_delete = false;
852 bool is_select = false; 852 bool is_select = false;
853 unsigned int profile; 853 unsigned int profile;
@@ -869,7 +869,7 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
869 domain = tomoyo_find_domain(data); 869 domain = tomoyo_find_domain(data);
870 else 870 else
871 domain = tomoyo_assign_domain(data, 0); 871 domain = tomoyo_assign_domain(data, 0);
872 head->write_var1 = domain; 872 head->w.domain = domain;
873 return 0; 873 return 0;
874 } 874 }
875 if (!domain) 875 if (!domain)
@@ -1250,7 +1250,7 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1250{ 1250{
1251 list_for_each_cookie(head->r.group, &tomoyo_group_list[idx]) { 1251 list_for_each_cookie(head->r.group, &tomoyo_group_list[idx]) {
1252 struct tomoyo_group *group = 1252 struct tomoyo_group *group =
1253 list_entry(head->r.group, typeof(*group), list); 1253 list_entry(head->r.group, typeof(*group), head.list);
1254 list_for_each_cookie(head->r.acl, &group->member_list) { 1254 list_for_each_cookie(head->r.acl, &group->member_list) {
1255 struct tomoyo_acl_head *ptr = 1255 struct tomoyo_acl_head *ptr =
1256 list_entry(head->r.acl, typeof(*ptr), list); 1256 list_entry(head->r.acl, typeof(*ptr), list);
@@ -1874,7 +1874,7 @@ int tomoyo_poll_control(struct file *file, poll_table *wait)
1874/** 1874/**
1875 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface. 1875 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
1876 * 1876 *
1877 * @file: Pointer to "struct file". 1877 * @head: Pointer to "struct tomoyo_io_buffer".
1878 * @buffer: Poiner to buffer to write to. 1878 * @buffer: Poiner to buffer to write to.
1879 * @buffer_len: Size of @buffer. 1879 * @buffer_len: Size of @buffer.
1880 * 1880 *
@@ -1882,11 +1882,10 @@ int tomoyo_poll_control(struct file *file, poll_table *wait)
1882 * 1882 *
1883 * Caller holds tomoyo_read_lock(). 1883 * Caller holds tomoyo_read_lock().
1884 */ 1884 */
1885int tomoyo_read_control(struct file *file, char __user *buffer, 1885int tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
1886 const int buffer_len) 1886 const int buffer_len)
1887{ 1887{
1888 int len; 1888 int len;
1889 struct tomoyo_io_buffer *head = file->private_data;
1890 1889
1891 if (!head->read) 1890 if (!head->read)
1892 return -ENOSYS; 1891 return -ENOSYS;
@@ -1906,7 +1905,7 @@ int tomoyo_read_control(struct file *file, char __user *buffer,
1906/** 1905/**
1907 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface. 1906 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
1908 * 1907 *
1909 * @file: Pointer to "struct file". 1908 * @head: Pointer to "struct tomoyo_io_buffer".
1910 * @buffer: Pointer to buffer to read from. 1909 * @buffer: Pointer to buffer to read from.
1911 * @buffer_len: Size of @buffer. 1910 * @buffer_len: Size of @buffer.
1912 * 1911 *
@@ -1914,10 +1913,9 @@ int tomoyo_read_control(struct file *file, char __user *buffer,
1914 * 1913 *
1915 * Caller holds tomoyo_read_lock(). 1914 * Caller holds tomoyo_read_lock().
1916 */ 1915 */
1917int tomoyo_write_control(struct file *file, const char __user *buffer, 1916int tomoyo_write_control(struct tomoyo_io_buffer *head,
1918 const int buffer_len) 1917 const char __user *buffer, const int buffer_len)
1919{ 1918{
1920 struct tomoyo_io_buffer *head = file->private_data;
1921 int error = buffer_len; 1919 int error = buffer_len;
1922 int avail_len = buffer_len; 1920 int avail_len = buffer_len;
1923 char *cp0 = head->write_buf; 1921 char *cp0 = head->write_buf;
@@ -1935,7 +1933,7 @@ int tomoyo_write_control(struct file *file, const char __user *buffer,
1935 /* Read a line and dispatch it to the policy handler. */ 1933 /* Read a line and dispatch it to the policy handler. */
1936 while (avail_len > 0) { 1934 while (avail_len > 0) {
1937 char c; 1935 char c;
1938 if (head->write_avail >= head->writebuf_size - 1) { 1936 if (head->w.avail >= head->writebuf_size - 1) {
1939 error = -ENOMEM; 1937 error = -ENOMEM;
1940 break; 1938 break;
1941 } else if (get_user(c, buffer)) { 1939 } else if (get_user(c, buffer)) {
@@ -1944,11 +1942,11 @@ int tomoyo_write_control(struct file *file, const char __user *buffer,
1944 } 1942 }
1945 buffer++; 1943 buffer++;
1946 avail_len--; 1944 avail_len--;
1947 cp0[head->write_avail++] = c; 1945 cp0[head->w.avail++] = c;
1948 if (c != '\n') 1946 if (c != '\n')
1949 continue; 1947 continue;
1950 cp0[head->write_avail - 1] = '\0'; 1948 cp0[head->w.avail - 1] = '\0';
1951 head->write_avail = 0; 1949 head->w.avail = 0;
1952 tomoyo_normalize_line(cp0); 1950 tomoyo_normalize_line(cp0);
1953 head->write(head); 1951 head->write(head);
1954 } 1952 }
@@ -1959,15 +1957,14 @@ int tomoyo_write_control(struct file *file, const char __user *buffer,
1959/** 1957/**
1960 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface. 1958 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface.
1961 * 1959 *
1962 * @file: Pointer to "struct file". 1960 * @head: Pointer to "struct tomoyo_io_buffer".
1963 * 1961 *
1964 * Releases memory and returns 0. 1962 * Releases memory and returns 0.
1965 * 1963 *
1966 * Caller looses tomoyo_read_lock(). 1964 * Caller looses tomoyo_read_lock().
1967 */ 1965 */
1968int tomoyo_close_control(struct file *file) 1966int tomoyo_close_control(struct tomoyo_io_buffer *head)
1969{ 1967{
1970 struct tomoyo_io_buffer *head = file->private_data;
1971 const bool is_write = !!head->write_buf; 1968 const bool is_write = !!head->write_buf;
1972 1969
1973 /* 1970 /*
@@ -1984,8 +1981,6 @@ int tomoyo_close_control(struct file *file)
1984 kfree(head->write_buf); 1981 kfree(head->write_buf);
1985 head->write_buf = NULL; 1982 head->write_buf = NULL;
1986 kfree(head); 1983 kfree(head);
1987 head = NULL;
1988 file->private_data = NULL;
1989 if (is_write) 1984 if (is_write)
1990 tomoyo_run_gc(); 1985 tomoyo_run_gc();
1991 return 0; 1986 return 0;
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index d0645733c102..7aa55eef67bd 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -219,6 +219,12 @@ struct tomoyo_acl_head {
219 bool is_deleted; 219 bool is_deleted;
220} __packed; 220} __packed;
221 221
222/* Common header for shared entries. */
223struct tomoyo_shared_acl_head {
224 struct list_head list;
225 atomic_t users;
226} __packed;
227
222/* Structure for request info. */ 228/* Structure for request info. */
223struct tomoyo_request_info { 229struct tomoyo_request_info {
224 struct tomoyo_domain_info *domain; 230 struct tomoyo_domain_info *domain;
@@ -281,8 +287,7 @@ struct tomoyo_path_info {
281 287
282/* Structure for holding string data. */ 288/* Structure for holding string data. */
283struct tomoyo_name { 289struct tomoyo_name {
284 struct list_head list; 290 struct tomoyo_shared_acl_head head;
285 atomic_t users;
286 struct tomoyo_path_info entry; 291 struct tomoyo_path_info entry;
287}; 292};
288 293
@@ -291,8 +296,6 @@ struct tomoyo_name_union {
291 /* Either @filename or @group is NULL. */ 296 /* Either @filename or @group is NULL. */
292 const struct tomoyo_path_info *filename; 297 const struct tomoyo_path_info *filename;
293 struct tomoyo_group *group; 298 struct tomoyo_group *group;
294 /* True if @group != NULL, false if @filename != NULL. */
295 u8 is_group;
296}; 299};
297 300
298/* Structure for holding a number. */ 301/* Structure for holding a number. */
@@ -300,18 +303,14 @@ struct tomoyo_number_union {
300 unsigned long values[2]; 303 unsigned long values[2];
301 struct tomoyo_group *group; /* Maybe NULL. */ 304 struct tomoyo_group *group; /* Maybe NULL. */
302 /* One of values in "enum tomoyo_value_type". */ 305 /* One of values in "enum tomoyo_value_type". */
303 u8 min_type; 306 u8 value_type[2];
304 u8 max_type;
305 /* True if @group != NULL, false otherwise. */
306 u8 is_group;
307}; 307};
308 308
309/* Structure for "path_group"/"number_group" directive. */ 309/* Structure for "path_group"/"number_group" directive. */
310struct tomoyo_group { 310struct tomoyo_group {
311 struct list_head list; 311 struct tomoyo_shared_acl_head head;
312 const struct tomoyo_path_info *group_name; 312 const struct tomoyo_path_info *group_name;
313 struct list_head member_list; 313 struct list_head member_list;
314 atomic_t users;
315}; 314};
316 315
317/* Structure for "path_group" directive. */ 316/* Structure for "path_group" directive. */
@@ -429,16 +428,18 @@ struct tomoyo_io_buffer {
429 bool print_execute_only; 428 bool print_execute_only;
430 const char *w[TOMOYO_MAX_IO_READ_QUEUE]; 429 const char *w[TOMOYO_MAX_IO_READ_QUEUE];
431 } r; 430 } r;
432 /* The position currently writing to. */ 431 struct {
433 struct tomoyo_domain_info *write_var1; 432 /* The position currently writing to. */
433 struct tomoyo_domain_info *domain;
434 /* Bytes available for writing. */
435 int avail;
436 } w;
434 /* Buffer for reading. */ 437 /* Buffer for reading. */
435 char *read_buf; 438 char *read_buf;
436 /* Size of read buffer. */ 439 /* Size of read buffer. */
437 int readbuf_size; 440 int readbuf_size;
438 /* Buffer for writing. */ 441 /* Buffer for writing. */
439 char *write_buf; 442 char *write_buf;
440 /* Bytes available for writing. */
441 int write_avail;
442 /* Size of write buffer. */ 443 /* Size of write buffer. */
443 int writebuf_size; 444 int writebuf_size;
444 /* Type of this interface. */ 445 /* Type of this interface. */
@@ -500,12 +501,12 @@ void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
500 __attribute__ ((format(printf, 2, 3))); 501 __attribute__ ((format(printf, 2, 3)));
501void tomoyo_check_profile(void); 502void tomoyo_check_profile(void);
502int tomoyo_open_control(const u8 type, struct file *file); 503int tomoyo_open_control(const u8 type, struct file *file);
503int tomoyo_close_control(struct file *file); 504int tomoyo_close_control(struct tomoyo_io_buffer *head);
504int tomoyo_poll_control(struct file *file, poll_table *wait); 505int tomoyo_poll_control(struct file *file, poll_table *wait);
505int tomoyo_read_control(struct file *file, char __user *buffer, 506int tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
506 const int buffer_len); 507 const int buffer_len);
507int tomoyo_write_control(struct file *file, const char __user *buffer, 508int tomoyo_write_control(struct tomoyo_io_buffer *head,
508 const int buffer_len); 509 const char __user *buffer, const int buffer_len);
509bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r); 510bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
510void tomoyo_warn_oom(const char *function); 511void tomoyo_warn_oom(const char *function);
511const struct tomoyo_path_info * 512const struct tomoyo_path_info *
@@ -672,30 +673,6 @@ static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a,
672} 673}
673 674
674/** 675/**
675 * tomoyo_valid - Check whether the character is a valid char.
676 *
677 * @c: The character to check.
678 *
679 * Returns true if @c is a valid character, false otherwise.
680 */
681static inline bool tomoyo_valid(const unsigned char c)
682{
683 return c > ' ' && c < 127;
684}
685
686/**
687 * tomoyo_invalid - Check whether the character is an invalid char.
688 *
689 * @c: The character to check.
690 *
691 * Returns true if @c is an invalid character, false otherwise.
692 */
693static inline bool tomoyo_invalid(const unsigned char c)
694{
695 return c && (c <= ' ' || c >= 127);
696}
697
698/**
699 * tomoyo_put_name - Drop reference on "struct tomoyo_name". 676 * tomoyo_put_name - Drop reference on "struct tomoyo_name".
700 * 677 *
701 * @name: Pointer to "struct tomoyo_path_info". Maybe NULL. 678 * @name: Pointer to "struct tomoyo_path_info". Maybe NULL.
@@ -707,7 +684,7 @@ static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
707 if (name) { 684 if (name) {
708 struct tomoyo_name *ptr = 685 struct tomoyo_name *ptr =
709 container_of(name, typeof(*ptr), entry); 686 container_of(name, typeof(*ptr), entry);
710 atomic_dec(&ptr->users); 687 atomic_dec(&ptr->head.users);
711 } 688 }
712} 689}
713 690
@@ -721,7 +698,7 @@ static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
721static inline void tomoyo_put_group(struct tomoyo_group *group) 698static inline void tomoyo_put_group(struct tomoyo_group *group)
722{ 699{
723 if (group) 700 if (group)
724 atomic_dec(&group->users); 701 atomic_dec(&group->head.users);
725} 702}
726 703
727/** 704/**
@@ -747,12 +724,6 @@ static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
747 return task_cred_xxx(task, security); 724 return task_cred_xxx(task, security);
748} 725}
749 726
750static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *p1,
751 const struct tomoyo_acl_info *p2)
752{
753 return p1->type == p2->type;
754}
755
756/** 727/**
757 * tomoyo_same_name_union - Check for duplicated "struct tomoyo_name_union" entry. 728 * tomoyo_same_name_union - Check for duplicated "struct tomoyo_name_union" entry.
758 * 729 *
@@ -764,8 +735,7 @@ static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *p1,
764static inline bool tomoyo_same_name_union 735static inline bool tomoyo_same_name_union
765(const struct tomoyo_name_union *a, const struct tomoyo_name_union *b) 736(const struct tomoyo_name_union *a, const struct tomoyo_name_union *b)
766{ 737{
767 return a->filename == b->filename && a->group == b->group && 738 return a->filename == b->filename && a->group == b->group;
768 a->is_group == b->is_group;
769} 739}
770 740
771/** 741/**
@@ -780,8 +750,8 @@ static inline bool tomoyo_same_number_union
780(const struct tomoyo_number_union *a, const struct tomoyo_number_union *b) 750(const struct tomoyo_number_union *a, const struct tomoyo_number_union *b)
781{ 751{
782 return a->values[0] == b->values[0] && a->values[1] == b->values[1] && 752 return a->values[0] == b->values[0] && a->values[1] == b->values[1] &&
783 a->group == b->group && a->min_type == b->min_type && 753 a->group == b->group && a->value_type[0] == b->value_type[0] &&
784 a->max_type == b->max_type && a->is_group == b->is_group; 754 a->value_type[1] == b->value_type[1];
785} 755}
786 756
787/** 757/**
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 355b536262b1..43977083254b 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -59,6 +59,20 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
59} 59}
60 60
61/** 61/**
62 * tomoyo_same_acl_head - Check for duplicated "struct tomoyo_acl_info" entry.
63 *
64 * @a: Pointer to "struct tomoyo_acl_info".
65 * @b: Pointer to "struct tomoyo_acl_info".
66 *
67 * Returns true if @a == @b, false otherwise.
68 */
69static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *a,
70 const struct tomoyo_acl_info *b)
71{
72 return a->type == b->type;
73}
74
75/**
62 * tomoyo_update_domain - Update an entry for domain policy. 76 * tomoyo_update_domain - Update an entry for domain policy.
63 * 77 *
64 * @new_entry: Pointer to "struct tomoyo_acl_info". 78 * @new_entry: Pointer to "struct tomoyo_acl_info".
@@ -88,7 +102,8 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
88 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 102 if (mutex_lock_interruptible(&tomoyo_policy_lock))
89 return error; 103 return error;
90 list_for_each_entry_rcu(entry, &domain->acl_info_list, list) { 104 list_for_each_entry_rcu(entry, &domain->acl_info_list, list) {
91 if (!check_duplicate(entry, new_entry)) 105 if (!tomoyo_same_acl_head(entry, new_entry) ||
106 !check_duplicate(entry, new_entry))
92 continue; 107 continue;
93 if (merge_duplicate) 108 if (merge_duplicate)
94 entry->is_deleted = merge_duplicate(entry, new_entry, 109 entry->is_deleted = merge_duplicate(entry, new_entry,
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 332380288078..4259e0a136d8 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -49,6 +49,9 @@ const char *tomoyo_path_number_keyword[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
49 [TOMOYO_TYPE_CHGRP] = "chgrp", 49 [TOMOYO_TYPE_CHGRP] = "chgrp",
50}; 50};
51 51
52/*
53 * Mapping table from "enum tomoyo_path_acl_index" to "enum tomoyo_mac_index".
54 */
52static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = { 55static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
53 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE, 56 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE,
54 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN, 57 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN,
@@ -63,17 +66,27 @@ static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
63 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT, 66 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT,
64}; 67};
65 68
69/*
70 * Mapping table from "enum tomoyo_mkdev_acl_index" to "enum tomoyo_mac_index".
71 */
66static const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = { 72static const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = {
67 [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK, 73 [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK,
68 [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR, 74 [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR,
69}; 75};
70 76
77/*
78 * Mapping table from "enum tomoyo_path2_acl_index" to "enum tomoyo_mac_index".
79 */
71static const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = { 80static const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = {
72 [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK, 81 [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK,
73 [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME, 82 [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME,
74 [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT, 83 [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT,
75}; 84};
76 85
86/*
87 * Mapping table from "enum tomoyo_path_number_acl_index" to
88 * "enum tomoyo_mac_index".
89 */
77static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = { 90static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
78 [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE, 91 [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE,
79 [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR, 92 [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR,
@@ -85,41 +98,76 @@ static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
85 [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP, 98 [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP,
86}; 99};
87 100
101/**
102 * tomoyo_put_name_union - Drop reference on "struct tomoyo_name_union".
103 *
104 * @ptr: Pointer to "struct tomoyo_name_union".
105 *
106 * Returns nothing.
107 */
88void tomoyo_put_name_union(struct tomoyo_name_union *ptr) 108void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
89{ 109{
90 if (!ptr) 110 tomoyo_put_group(ptr->group);
91 return; 111 tomoyo_put_name(ptr->filename);
92 if (ptr->is_group)
93 tomoyo_put_group(ptr->group);
94 else
95 tomoyo_put_name(ptr->filename);
96} 112}
97 113
114/**
115 * tomoyo_compare_name_union - Check whether a name matches "struct tomoyo_name_union" or not.
116 *
117 * @name: Pointer to "struct tomoyo_path_info".
118 * @ptr: Pointer to "struct tomoyo_name_union".
119 *
120 * Returns "struct tomoyo_path_info" if @name matches @ptr, NULL otherwise.
121 */
98const struct tomoyo_path_info * 122const struct tomoyo_path_info *
99tomoyo_compare_name_union(const struct tomoyo_path_info *name, 123tomoyo_compare_name_union(const struct tomoyo_path_info *name,
100 const struct tomoyo_name_union *ptr) 124 const struct tomoyo_name_union *ptr)
101{ 125{
102 if (ptr->is_group) 126 if (ptr->group)
103 return tomoyo_path_matches_group(name, ptr->group); 127 return tomoyo_path_matches_group(name, ptr->group);
104 if (tomoyo_path_matches_pattern(name, ptr->filename)) 128 if (tomoyo_path_matches_pattern(name, ptr->filename))
105 return ptr->filename; 129 return ptr->filename;
106 return NULL; 130 return NULL;
107} 131}
108 132
133/**
134 * tomoyo_put_number_union - Drop reference on "struct tomoyo_number_union".
135 *
136 * @ptr: Pointer to "struct tomoyo_number_union".
137 *
138 * Returns nothing.
139 */
109void tomoyo_put_number_union(struct tomoyo_number_union *ptr) 140void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
110{ 141{
111 if (ptr && ptr->is_group) 142 tomoyo_put_group(ptr->group);
112 tomoyo_put_group(ptr->group);
113} 143}
114 144
145/**
146 * tomoyo_compare_number_union - Check whether a value matches "struct tomoyo_number_union" or not.
147 *
148 * @value: Number to check.
149 * @ptr: Pointer to "struct tomoyo_number_union".
150 *
151 * Returns true if @value matches @ptr, false otherwise.
152 */
115bool tomoyo_compare_number_union(const unsigned long value, 153bool tomoyo_compare_number_union(const unsigned long value,
116 const struct tomoyo_number_union *ptr) 154 const struct tomoyo_number_union *ptr)
117{ 155{
118 if (ptr->is_group) 156 if (ptr->group)
119 return tomoyo_number_matches_group(value, value, ptr->group); 157 return tomoyo_number_matches_group(value, value, ptr->group);
120 return value >= ptr->values[0] && value <= ptr->values[1]; 158 return value >= ptr->values[0] && value <= ptr->values[1];
121} 159}
122 160
161/**
162 * tomoyo_add_slash - Add trailing '/' if needed.
163 *
164 * @buf: Pointer to "struct tomoyo_path_info".
165 *
166 * Returns nothing.
167 *
168 * @buf must be generated by tomoyo_encode() because this function does not
169 * allocate memory for adding '/'.
170 */
123static void tomoyo_add_slash(struct tomoyo_path_info *buf) 171static void tomoyo_add_slash(struct tomoyo_path_info *buf)
124{ 172{
125 if (buf->is_dir) 173 if (buf->is_dir)
@@ -247,6 +295,18 @@ static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
247 filename->name, buffer); 295 filename->name, buffer);
248} 296}
249 297
298/**
299 * tomoyo_check_path_acl - Check permission for path operation.
300 *
301 * @r: Pointer to "struct tomoyo_request_info".
302 * @ptr: Pointer to "struct tomoyo_acl_info".
303 *
304 * Returns true if granted, false otherwise.
305 *
306 * To be able to use wildcard for domain transition, this function sets
307 * matching entry on success. Since the caller holds tomoyo_read_lock(),
308 * it is safe to set matching entry.
309 */
250static bool tomoyo_check_path_acl(struct tomoyo_request_info *r, 310static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
251 const struct tomoyo_acl_info *ptr) 311 const struct tomoyo_acl_info *ptr)
252{ 312{
@@ -261,6 +321,14 @@ static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
261 return false; 321 return false;
262} 322}
263 323
324/**
325 * tomoyo_check_path_number_acl - Check permission for path number operation.
326 *
327 * @r: Pointer to "struct tomoyo_request_info".
328 * @ptr: Pointer to "struct tomoyo_acl_info".
329 *
330 * Returns true if granted, false otherwise.
331 */
264static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r, 332static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
265 const struct tomoyo_acl_info *ptr) 333 const struct tomoyo_acl_info *ptr)
266{ 334{
@@ -273,6 +341,14 @@ static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
273 &acl->name); 341 &acl->name);
274} 342}
275 343
344/**
345 * tomoyo_check_path2_acl - Check permission for path path operation.
346 *
347 * @r: Pointer to "struct tomoyo_request_info".
348 * @ptr: Pointer to "struct tomoyo_acl_info".
349 *
350 * Returns true if granted, false otherwise.
351 */
276static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r, 352static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
277 const struct tomoyo_acl_info *ptr) 353 const struct tomoyo_acl_info *ptr)
278{ 354{
@@ -284,8 +360,16 @@ static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
284 &acl->name2); 360 &acl->name2);
285} 361}
286 362
363/**
364 * tomoyo_check_mkdev_acl - Check permission for path number number number operation.
365 *
366 * @r: Pointer to "struct tomoyo_request_info".
367 * @ptr: Pointer to "struct tomoyo_acl_info".
368 *
369 * Returns true if granted, false otherwise.
370 */
287static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r, 371static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
288 const struct tomoyo_acl_info *ptr) 372 const struct tomoyo_acl_info *ptr)
289{ 373{
290 const struct tomoyo_mkdev_acl *acl = 374 const struct tomoyo_mkdev_acl *acl =
291 container_of(ptr, typeof(*acl), head); 375 container_of(ptr, typeof(*acl), head);
@@ -300,13 +384,20 @@ static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
300 &acl->name); 384 &acl->name);
301} 385}
302 386
387/**
388 * tomoyo_same_path_acl - Check for duplicated "struct tomoyo_path_acl" entry.
389 *
390 * @a: Pointer to "struct tomoyo_acl_info".
391 * @b: Pointer to "struct tomoyo_acl_info".
392 *
393 * Returns true if @a == @b except permission bits, false otherwise.
394 */
303static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a, 395static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a,
304 const struct tomoyo_acl_info *b) 396 const struct tomoyo_acl_info *b)
305{ 397{
306 const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head); 398 const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head);
307 const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head); 399 const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head);
308 return tomoyo_same_acl_head(&p1->head, &p2->head) && 400 return tomoyo_same_name_union(&p1->name, &p2->name);
309 tomoyo_same_name_union(&p1->name, &p2->name);
310} 401}
311 402
312/** 403/**
@@ -364,23 +455,37 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename,
364 return error; 455 return error;
365} 456}
366 457
458/**
459 * tomoyo_same_mkdev_acl - Check for duplicated "struct tomoyo_mkdev_acl" entry.
460 *
461 * @a: Pointer to "struct tomoyo_acl_info".
462 * @b: Pointer to "struct tomoyo_acl_info".
463 *
464 * Returns true if @a == @b except permission bits, false otherwise.
465 */
367static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a, 466static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a,
368 const struct tomoyo_acl_info *b) 467 const struct tomoyo_acl_info *b)
369{ 468{
370 const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), 469 const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), head);
371 head); 470 const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), head);
372 const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), 471 return tomoyo_same_name_union(&p1->name, &p2->name) &&
373 head); 472 tomoyo_same_number_union(&p1->mode, &p2->mode) &&
374 return tomoyo_same_acl_head(&p1->head, &p2->head) 473 tomoyo_same_number_union(&p1->major, &p2->major) &&
375 && tomoyo_same_name_union(&p1->name, &p2->name) 474 tomoyo_same_number_union(&p1->minor, &p2->minor);
376 && tomoyo_same_number_union(&p1->mode, &p2->mode)
377 && tomoyo_same_number_union(&p1->major, &p2->major)
378 && tomoyo_same_number_union(&p1->minor, &p2->minor);
379} 475}
380 476
477/**
478 * tomoyo_merge_mkdev_acl - Merge duplicated "struct tomoyo_mkdev_acl" entry.
479 *
480 * @a: Pointer to "struct tomoyo_acl_info".
481 * @b: Pointer to "struct tomoyo_acl_info".
482 * @is_delete: True for @a &= ~@b, false for @a |= @b.
483 *
484 * Returns true if @a is empty, false otherwise.
485 */
381static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a, 486static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
382 struct tomoyo_acl_info *b, 487 struct tomoyo_acl_info *b,
383 const bool is_delete) 488 const bool is_delete)
384{ 489{
385 u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl, 490 u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl,
386 head)->perm; 491 head)->perm;
@@ -411,9 +516,9 @@ static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
411 * Caller holds tomoyo_read_lock(). 516 * Caller holds tomoyo_read_lock().
412 */ 517 */
413static int tomoyo_update_mkdev_acl(const u8 type, const char *filename, 518static int tomoyo_update_mkdev_acl(const u8 type, const char *filename,
414 char *mode, char *major, char *minor, 519 char *mode, char *major, char *minor,
415 struct tomoyo_domain_info * const 520 struct tomoyo_domain_info * const domain,
416 domain, const bool is_delete) 521 const bool is_delete)
417{ 522{
418 struct tomoyo_mkdev_acl e = { 523 struct tomoyo_mkdev_acl e = {
419 .head.type = TOMOYO_TYPE_MKDEV_ACL, 524 .head.type = TOMOYO_TYPE_MKDEV_ACL,
@@ -436,16 +541,32 @@ static int tomoyo_update_mkdev_acl(const u8 type, const char *filename,
436 return error; 541 return error;
437} 542}
438 543
544/**
545 * tomoyo_same_path2_acl - Check for duplicated "struct tomoyo_path2_acl" entry.
546 *
547 * @a: Pointer to "struct tomoyo_acl_info".
548 * @b: Pointer to "struct tomoyo_acl_info".
549 *
550 * Returns true if @a == @b except permission bits, false otherwise.
551 */
439static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a, 552static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a,
440 const struct tomoyo_acl_info *b) 553 const struct tomoyo_acl_info *b)
441{ 554{
442 const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head); 555 const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head);
443 const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head); 556 const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head);
444 return tomoyo_same_acl_head(&p1->head, &p2->head) 557 return tomoyo_same_name_union(&p1->name1, &p2->name1) &&
445 && tomoyo_same_name_union(&p1->name1, &p2->name1) 558 tomoyo_same_name_union(&p1->name2, &p2->name2);
446 && tomoyo_same_name_union(&p1->name2, &p2->name2);
447} 559}
448 560
561/**
562 * tomoyo_merge_path2_acl - Merge duplicated "struct tomoyo_path2_acl" entry.
563 *
564 * @a: Pointer to "struct tomoyo_acl_info".
565 * @b: Pointer to "struct tomoyo_acl_info".
566 * @is_delete: True for @a &= ~@b, false for @a |= @b.
567 *
568 * Returns true if @a is empty, false otherwise.
569 */
449static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a, 570static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a,
450 struct tomoyo_acl_info *b, 571 struct tomoyo_acl_info *b,
451 const bool is_delete) 572 const bool is_delete)
@@ -532,6 +653,14 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
532 return error; 653 return error;
533} 654}
534 655
656/**
657 * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry.
658 *
659 * @a: Pointer to "struct tomoyo_acl_info".
660 * @b: Pointer to "struct tomoyo_acl_info".
661 *
662 * Returns true if @a == @b except permission bits, false otherwise.
663 */
535static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a, 664static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
536 const struct tomoyo_acl_info *b) 665 const struct tomoyo_acl_info *b)
537{ 666{
@@ -539,11 +668,19 @@ static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
539 head); 668 head);
540 const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2), 669 const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2),
541 head); 670 head);
542 return tomoyo_same_acl_head(&p1->head, &p2->head) 671 return tomoyo_same_name_union(&p1->name, &p2->name) &&
543 && tomoyo_same_name_union(&p1->name, &p2->name) 672 tomoyo_same_number_union(&p1->number, &p2->number);
544 && tomoyo_same_number_union(&p1->number, &p2->number);
545} 673}
546 674
675/**
676 * tomoyo_merge_path_number_acl - Merge duplicated "struct tomoyo_path_number_acl" entry.
677 *
678 * @a: Pointer to "struct tomoyo_acl_info".
679 * @b: Pointer to "struct tomoyo_acl_info".
680 * @is_delete: True for @a &= ~@b, false for @a |= @b.
681 *
682 * Returns true if @a is empty, false otherwise.
683 */
547static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a, 684static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
548 struct tomoyo_acl_info *b, 685 struct tomoyo_acl_info *b,
549 const bool is_delete) 686 const bool is_delete)
@@ -575,8 +712,7 @@ static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
575static int tomoyo_update_path_number_acl(const u8 type, const char *filename, 712static int tomoyo_update_path_number_acl(const u8 type, const char *filename,
576 char *number, 713 char *number,
577 struct tomoyo_domain_info * const 714 struct tomoyo_domain_info * const
578 domain, 715 domain, const bool is_delete)
579 const bool is_delete)
580{ 716{
581 struct tomoyo_path_number_acl e = { 717 struct tomoyo_path_number_acl e = {
582 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL, 718 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
@@ -737,7 +873,7 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
737 * Returns 0 on success, negative value otherwise. 873 * Returns 0 on success, negative value otherwise.
738 */ 874 */
739int tomoyo_mkdev_perm(const u8 operation, struct path *path, 875int tomoyo_mkdev_perm(const u8 operation, struct path *path,
740 const unsigned int mode, unsigned int dev) 876 const unsigned int mode, unsigned int dev)
741{ 877{
742 struct tomoyo_request_info r; 878 struct tomoyo_request_info r;
743 int error = -ENOMEM; 879 int error = -ENOMEM;
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index ba799b49ee3a..de14030823cd 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -13,13 +13,30 @@
13 13
14struct tomoyo_gc { 14struct tomoyo_gc {
15 struct list_head list; 15 struct list_head list;
16 int type; 16 enum tomoyo_policy_id type;
17 struct list_head *element; 17 struct list_head *element;
18}; 18};
19static LIST_HEAD(tomoyo_gc_queue); 19static LIST_HEAD(tomoyo_gc_queue);
20static DEFINE_MUTEX(tomoyo_gc_mutex); 20static DEFINE_MUTEX(tomoyo_gc_mutex);
21 21
22/* Caller holds tomoyo_policy_lock mutex. */ 22/**
23 * tomoyo_add_to_gc - Add an entry to to be deleted list.
24 *
25 * @type: One of values in "enum tomoyo_policy_id".
26 * @element: Pointer to "struct list_head".
27 *
28 * Returns true on success, false otherwise.
29 *
30 * Caller holds tomoyo_policy_lock mutex.
31 *
32 * Adding an entry needs kmalloc(). Thus, if we try to add thousands of
33 * entries at once, it will take too long time. Thus, do not add more than 128
34 * entries per a scan. But to be able to handle worst case where all entries
35 * are in-use, we accept one more entry per a scan.
36 *
37 * If we use singly linked list using "struct list_head"->prev (which is
38 * LIST_POISON2), we can avoid kmalloc().
39 */
23static bool tomoyo_add_to_gc(const int type, struct list_head *element) 40static bool tomoyo_add_to_gc(const int type, struct list_head *element)
24{ 41{
25 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 42 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
@@ -32,6 +49,13 @@ static bool tomoyo_add_to_gc(const int type, struct list_head *element)
32 return true; 49 return true;
33} 50}
34 51
52/**
53 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
54 *
55 * @element: Pointer to "struct list_head".
56 *
57 * Returns nothing.
58 */
35static void tomoyo_del_transition_control(struct list_head *element) 59static void tomoyo_del_transition_control(struct list_head *element)
36{ 60{
37 struct tomoyo_transition_control *ptr = 61 struct tomoyo_transition_control *ptr =
@@ -40,6 +64,13 @@ static void tomoyo_del_transition_control(struct list_head *element)
40 tomoyo_put_name(ptr->program); 64 tomoyo_put_name(ptr->program);
41} 65}
42 66
67/**
68 * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
69 *
70 * @element: Pointer to "struct list_head".
71 *
72 * Returns nothing.
73 */
43static void tomoyo_del_aggregator(struct list_head *element) 74static void tomoyo_del_aggregator(struct list_head *element)
44{ 75{
45 struct tomoyo_aggregator *ptr = 76 struct tomoyo_aggregator *ptr =
@@ -48,6 +79,13 @@ static void tomoyo_del_aggregator(struct list_head *element)
48 tomoyo_put_name(ptr->aggregated_name); 79 tomoyo_put_name(ptr->aggregated_name);
49} 80}
50 81
82/**
83 * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
84 *
85 * @element: Pointer to "struct list_head".
86 *
87 * Returns nothing.
88 */
51static void tomoyo_del_manager(struct list_head *element) 89static void tomoyo_del_manager(struct list_head *element)
52{ 90{
53 struct tomoyo_manager *ptr = 91 struct tomoyo_manager *ptr =
@@ -55,6 +93,13 @@ static void tomoyo_del_manager(struct list_head *element)
55 tomoyo_put_name(ptr->manager); 93 tomoyo_put_name(ptr->manager);
56} 94}
57 95
96/**
97 * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
98 *
99 * @element: Pointer to "struct list_head".
100 *
101 * Returns nothing.
102 */
58static void tomoyo_del_acl(struct list_head *element) 103static void tomoyo_del_acl(struct list_head *element)
59{ 104{
60 struct tomoyo_acl_info *acl = 105 struct tomoyo_acl_info *acl =
@@ -145,12 +190,26 @@ static bool tomoyo_del_domain(struct list_head *element)
145} 190}
146 191
147 192
193/**
194 * tomoyo_del_name - Delete members in "struct tomoyo_name".
195 *
196 * @element: Pointer to "struct list_head".
197 *
198 * Returns nothing.
199 */
148static void tomoyo_del_name(struct list_head *element) 200static void tomoyo_del_name(struct list_head *element)
149{ 201{
150 const struct tomoyo_name *ptr = 202 const struct tomoyo_name *ptr =
151 container_of(element, typeof(*ptr), list); 203 container_of(element, typeof(*ptr), head.list);
152} 204}
153 205
206/**
207 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
208 *
209 * @element: Pointer to "struct list_head".
210 *
211 * Returns nothing.
212 */
154static void tomoyo_del_path_group(struct list_head *element) 213static void tomoyo_del_path_group(struct list_head *element)
155{ 214{
156 struct tomoyo_path_group *member = 215 struct tomoyo_path_group *member =
@@ -158,20 +217,43 @@ static void tomoyo_del_path_group(struct list_head *element)
158 tomoyo_put_name(member->member_name); 217 tomoyo_put_name(member->member_name);
159} 218}
160 219
220/**
221 * tomoyo_del_group - Delete "struct tomoyo_group".
222 *
223 * @element: Pointer to "struct list_head".
224 *
225 * Returns nothing.
226 */
161static void tomoyo_del_group(struct list_head *element) 227static void tomoyo_del_group(struct list_head *element)
162{ 228{
163 struct tomoyo_group *group = 229 struct tomoyo_group *group =
164 container_of(element, typeof(*group), list); 230 container_of(element, typeof(*group), head.list);
165 tomoyo_put_name(group->group_name); 231 tomoyo_put_name(group->group_name);
166} 232}
167 233
234/**
235 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
236 *
237 * @element: Pointer to "struct list_head".
238 *
239 * Returns nothing.
240 */
168static void tomoyo_del_number_group(struct list_head *element) 241static void tomoyo_del_number_group(struct list_head *element)
169{ 242{
170 struct tomoyo_number_group *member = 243 struct tomoyo_number_group *member =
171 container_of(element, typeof(*member), head.list); 244 container_of(element, typeof(*member), head.list);
172} 245}
173 246
174static bool tomoyo_collect_member(struct list_head *member_list, int id) 247/**
248 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
249 *
250 * @id: One of values in "enum tomoyo_policy_id".
251 * @member_list: Pointer to "struct list_head".
252 *
253 * Returns true if some elements are deleted, false otherwise.
254 */
255static bool tomoyo_collect_member(const enum tomoyo_policy_id id,
256 struct list_head *member_list)
175{ 257{
176 struct tomoyo_acl_head *member; 258 struct tomoyo_acl_head *member;
177 list_for_each_entry(member, member_list, list) { 259 list_for_each_entry(member, member_list, list) {
@@ -195,13 +277,18 @@ static bool tomoyo_collect_acl(struct tomoyo_domain_info *domain)
195 return true; 277 return true;
196} 278}
197 279
280/**
281 * tomoyo_collect_entry - Scan lists for deleted elements.
282 *
283 * Returns nothing.
284 */
198static void tomoyo_collect_entry(void) 285static void tomoyo_collect_entry(void)
199{ 286{
200 int i; 287 int i;
201 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 288 if (mutex_lock_interruptible(&tomoyo_policy_lock))
202 return; 289 return;
203 for (i = 0; i < TOMOYO_MAX_POLICY; i++) { 290 for (i = 0; i < TOMOYO_MAX_POLICY; i++) {
204 if (!tomoyo_collect_member(&tomoyo_policy_list[i], i)) 291 if (!tomoyo_collect_member(i, &tomoyo_policy_list[i]))
205 goto unlock; 292 goto unlock;
206 } 293 }
207 { 294 {
@@ -222,10 +309,10 @@ static void tomoyo_collect_entry(void)
222 } 309 }
223 for (i = 0; i < TOMOYO_MAX_HASH; i++) { 310 for (i = 0; i < TOMOYO_MAX_HASH; i++) {
224 struct tomoyo_name *ptr; 311 struct tomoyo_name *ptr;
225 list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], list) { 312 list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], head.list) {
226 if (atomic_read(&ptr->users)) 313 if (atomic_read(&ptr->head.users))
227 continue; 314 continue;
228 if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->list)) 315 if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->head.list))
229 goto unlock; 316 goto unlock;
230 } 317 }
231 } 318 }
@@ -241,13 +328,14 @@ static void tomoyo_collect_entry(void)
241 id = TOMOYO_ID_NUMBER_GROUP; 328 id = TOMOYO_ID_NUMBER_GROUP;
242 break; 329 break;
243 } 330 }
244 list_for_each_entry(group, list, list) { 331 list_for_each_entry(group, list, head.list) {
245 if (!tomoyo_collect_member(&group->member_list, id)) 332 if (!tomoyo_collect_member(id, &group->member_list))
246 goto unlock; 333 goto unlock;
247 if (!list_empty(&group->member_list) || 334 if (!list_empty(&group->member_list) ||
248 atomic_read(&group->users)) 335 atomic_read(&group->head.users))
249 continue; 336 continue;
250 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP, &group->list)) 337 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP,
338 &group->head.list))
251 goto unlock; 339 goto unlock;
252 } 340 }
253 } 341 }
@@ -291,6 +379,8 @@ static void tomoyo_kfree_entry(void)
291 case TOMOYO_ID_NUMBER_GROUP: 379 case TOMOYO_ID_NUMBER_GROUP:
292 tomoyo_del_number_group(element); 380 tomoyo_del_number_group(element);
293 break; 381 break;
382 case TOMOYO_MAX_POLICY:
383 break;
294 } 384 }
295 tomoyo_memory_free(element); 385 tomoyo_memory_free(element);
296 list_del(&p->list); 386 list_del(&p->list);
@@ -298,6 +388,17 @@ static void tomoyo_kfree_entry(void)
298 } 388 }
299} 389}
300 390
391/**
392 * tomoyo_gc_thread - Garbage collector thread function.
393 *
394 * @unused: Unused.
395 *
396 * In case OOM-killer choose this thread for termination, we create this thread
397 * as a short live thread whenever /sys/kernel/security/tomoyo/ interface was
398 * close()d.
399 *
400 * Returns 0.
401 */
301static int tomoyo_gc_thread(void *unused) 402static int tomoyo_gc_thread(void *unused)
302{ 403{
303 daemonize("GC for TOMOYO"); 404 daemonize("GC for TOMOYO");
diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c
index 42a7b1ba8cbf..dfef0cb268dc 100644
--- a/security/tomoyo/memory.c
+++ b/security/tomoyo/memory.c
@@ -110,10 +110,10 @@ struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 idx)
110 return NULL; 110 return NULL;
111 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 111 if (mutex_lock_interruptible(&tomoyo_policy_lock))
112 goto out; 112 goto out;
113 list_for_each_entry(group, &tomoyo_group_list[idx], list) { 113 list_for_each_entry(group, &tomoyo_group_list[idx], head.list) {
114 if (e.group_name != group->group_name) 114 if (e.group_name != group->group_name)
115 continue; 115 continue;
116 atomic_inc(&group->users); 116 atomic_inc(&group->head.users);
117 found = true; 117 found = true;
118 break; 118 break;
119 } 119 }
@@ -121,8 +121,8 @@ struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 idx)
121 struct tomoyo_group *entry = tomoyo_commit_ok(&e, sizeof(e)); 121 struct tomoyo_group *entry = tomoyo_commit_ok(&e, sizeof(e));
122 if (entry) { 122 if (entry) {
123 INIT_LIST_HEAD(&entry->member_list); 123 INIT_LIST_HEAD(&entry->member_list);
124 atomic_set(&entry->users, 1); 124 atomic_set(&entry->head.users, 1);
125 list_add_tail_rcu(&entry->list, 125 list_add_tail_rcu(&entry->head.list,
126 &tomoyo_group_list[idx]); 126 &tomoyo_group_list[idx]);
127 group = entry; 127 group = entry;
128 found = true; 128 found = true;
@@ -164,10 +164,10 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
164 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; 164 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
165 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 165 if (mutex_lock_interruptible(&tomoyo_policy_lock))
166 return NULL; 166 return NULL;
167 list_for_each_entry(ptr, head, list) { 167 list_for_each_entry(ptr, head, head.list) {
168 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) 168 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
169 continue; 169 continue;
170 atomic_inc(&ptr->users); 170 atomic_inc(&ptr->head.users);
171 goto out; 171 goto out;
172 } 172 }
173 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS); 173 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS);
@@ -183,9 +183,9 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
183 atomic_add(allocated_len, &tomoyo_policy_memory_size); 183 atomic_add(allocated_len, &tomoyo_policy_memory_size);
184 ptr->entry.name = ((char *) ptr) + sizeof(*ptr); 184 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
185 memmove((char *) ptr->entry.name, name, len); 185 memmove((char *) ptr->entry.name, name, len);
186 atomic_set(&ptr->users, 1); 186 atomic_set(&ptr->head.users, 1);
187 tomoyo_fill_path_info(&ptr->entry); 187 tomoyo_fill_path_info(&ptr->entry);
188 list_add_tail(&ptr->list, head); 188 list_add_tail(&ptr->head.list, head);
189 out: 189 out:
190 mutex_unlock(&tomoyo_policy_lock); 190 mutex_unlock(&tomoyo_policy_lock);
191 return ptr ? &ptr->entry : NULL; 191 return ptr ? &ptr->entry : NULL;
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index 5cfc72078742..7649dbc6a56b 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -52,16 +52,28 @@ static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
52 r->param.mount.dir->name, type, flags); 52 r->param.mount.dir->name, type, flags);
53} 53}
54 54
55/**
56 * tomoyo_check_mount_acl - Check permission for path path path number operation.
57 *
58 * @r: Pointer to "struct tomoyo_request_info".
59 * @ptr: Pointer to "struct tomoyo_acl_info".
60 *
61 * Returns true if granted, false otherwise.
62 */
55static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r, 63static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
56 const struct tomoyo_acl_info *ptr) 64 const struct tomoyo_acl_info *ptr)
57{ 65{
58 const struct tomoyo_mount_acl *acl = 66 const struct tomoyo_mount_acl *acl =
59 container_of(ptr, typeof(*acl), head); 67 container_of(ptr, typeof(*acl), head);
60 return tomoyo_compare_number_union(r->param.mount.flags, &acl->flags) && 68 return tomoyo_compare_number_union(r->param.mount.flags,
61 tomoyo_compare_name_union(r->param.mount.type, &acl->fs_type) && 69 &acl->flags) &&
62 tomoyo_compare_name_union(r->param.mount.dir, &acl->dir_name) && 70 tomoyo_compare_name_union(r->param.mount.type,
71 &acl->fs_type) &&
72 tomoyo_compare_name_union(r->param.mount.dir,
73 &acl->dir_name) &&
63 (!r->param.mount.need_dev || 74 (!r->param.mount.need_dev ||
64 tomoyo_compare_name_union(r->param.mount.dev, &acl->dev_name)); 75 tomoyo_compare_name_union(r->param.mount.dev,
76 &acl->dev_name));
65} 77}
66 78
67/** 79/**
@@ -232,13 +244,20 @@ int tomoyo_mount_permission(char *dev_name, struct path *path,
232 return error; 244 return error;
233} 245}
234 246
247/**
248 * tomoyo_same_mount_acl - Check for duplicated "struct tomoyo_mount_acl" entry.
249 *
250 * @a: Pointer to "struct tomoyo_acl_info".
251 * @b: Pointer to "struct tomoyo_acl_info".
252 *
253 * Returns true if @a == @b, false otherwise.
254 */
235static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a, 255static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a,
236 const struct tomoyo_acl_info *b) 256 const struct tomoyo_acl_info *b)
237{ 257{
238 const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head); 258 const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head);
239 const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head); 259 const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head);
240 return tomoyo_same_acl_head(&p1->head, &p2->head) && 260 return tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
241 tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
242 tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) && 261 tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) &&
243 tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) && 262 tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) &&
244 tomoyo_same_number_union(&p1->flags, &p2->flags); 263 tomoyo_same_number_union(&p1->flags, &p2->flags);
diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c
index a5bd76d7f6be..6410868c8a3d 100644
--- a/security/tomoyo/securityfs_if.c
+++ b/security/tomoyo/securityfs_if.c
@@ -34,7 +34,7 @@ static int tomoyo_open(struct inode *inode, struct file *file)
34 */ 34 */
35static int tomoyo_release(struct inode *inode, struct file *file) 35static int tomoyo_release(struct inode *inode, struct file *file)
36{ 36{
37 return tomoyo_close_control(file); 37 return tomoyo_close_control(file->private_data);
38} 38}
39 39
40/** 40/**
@@ -63,7 +63,7 @@ static unsigned int tomoyo_poll(struct file *file, poll_table *wait)
63static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count, 63static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
64 loff_t *ppos) 64 loff_t *ppos)
65{ 65{
66 return tomoyo_read_control(file, buf, count); 66 return tomoyo_read_control(file->private_data, buf, count);
67} 67}
68 68
69/** 69/**
@@ -79,7 +79,7 @@ static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
79static ssize_t tomoyo_write(struct file *file, const char __user *buf, 79static ssize_t tomoyo_write(struct file *file, const char __user *buf,
80 size_t count, loff_t *ppos) 80 size_t count, loff_t *ppos)
81{ 81{
82 return tomoyo_write_control(file, buf, count); 82 return tomoyo_write_control(file->private_data, buf, count);
83} 83}
84 84
85/* 85/*
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 7fb9bbf7021a..abb177c2d7c2 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -21,7 +21,7 @@ bool tomoyo_policy_loaded;
21 * @result: Pointer to "unsigned long". 21 * @result: Pointer to "unsigned long".
22 * @str: Pointer to string to parse. 22 * @str: Pointer to string to parse.
23 * 23 *
24 * Returns value type on success, 0 otherwise. 24 * Returns one of values in "enum tomoyo_value_type".
25 * 25 *
26 * The @src is updated to point the first character after the value 26 * The @src is updated to point the first character after the value
27 * on success. 27 * on success.
@@ -43,7 +43,7 @@ static u8 tomoyo_parse_ulong(unsigned long *result, char **str)
43 } 43 }
44 *result = simple_strtoul(cp, &ep, base); 44 *result = simple_strtoul(cp, &ep, base);
45 if (cp == ep) 45 if (cp == ep)
46 return 0; 46 return TOMOYO_VALUE_TYPE_INVALID;
47 *str = ep; 47 *str = ep;
48 switch (base) { 48 switch (base) {
49 case 16: 49 case 16:
@@ -93,11 +93,9 @@ bool tomoyo_parse_name_union(const char *filename,
93 return false; 93 return false;
94 if (filename[0] == '@') { 94 if (filename[0] == '@') {
95 ptr->group = tomoyo_get_group(filename + 1, TOMOYO_PATH_GROUP); 95 ptr->group = tomoyo_get_group(filename + 1, TOMOYO_PATH_GROUP);
96 ptr->is_group = true;
97 return ptr->group != NULL; 96 return ptr->group != NULL;
98 } 97 }
99 ptr->filename = tomoyo_get_name(filename); 98 ptr->filename = tomoyo_get_name(filename);
100 ptr->is_group = false;
101 return ptr->filename != NULL; 99 return ptr->filename != NULL;
102} 100}
103 101
@@ -118,17 +116,16 @@ bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num)
118 if (!tomoyo_correct_word(data)) 116 if (!tomoyo_correct_word(data))
119 return false; 117 return false;
120 num->group = tomoyo_get_group(data + 1, TOMOYO_NUMBER_GROUP); 118 num->group = tomoyo_get_group(data + 1, TOMOYO_NUMBER_GROUP);
121 num->is_group = true;
122 return num->group != NULL; 119 return num->group != NULL;
123 } 120 }
124 type = tomoyo_parse_ulong(&v, &data); 121 type = tomoyo_parse_ulong(&v, &data);
125 if (!type) 122 if (!type)
126 return false; 123 return false;
127 num->values[0] = v; 124 num->values[0] = v;
128 num->min_type = type; 125 num->value_type[0] = type;
129 if (!*data) { 126 if (!*data) {
130 num->values[1] = v; 127 num->values[1] = v;
131 num->max_type = type; 128 num->value_type[1] = type;
132 return true; 129 return true;
133 } 130 }
134 if (*data++ != '-') 131 if (*data++ != '-')
@@ -137,7 +134,7 @@ bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num)
137 if (!type || *data) 134 if (!type || *data)
138 return false; 135 return false;
139 num->values[1] = v; 136 num->values[1] = v;
140 num->max_type = type; 137 num->value_type[1] = type;
141 return true; 138 return true;
142} 139}
143 140
@@ -185,6 +182,30 @@ static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3)
185} 182}
186 183
187/** 184/**
185 * tomoyo_valid - Check whether the character is a valid char.
186 *
187 * @c: The character to check.
188 *
189 * Returns true if @c is a valid character, false otherwise.
190 */
191static inline bool tomoyo_valid(const unsigned char c)
192{
193 return c > ' ' && c < 127;
194}
195
196/**
197 * tomoyo_invalid - Check whether the character is an invalid char.
198 *
199 * @c: The character to check.
200 *
201 * Returns true if @c is an invalid character, false otherwise.
202 */
203static inline bool tomoyo_invalid(const unsigned char c)
204{
205 return c && (c <= ' ' || c >= 127);
206}
207
208/**
188 * tomoyo_str_starts - Check whether the given string starts with the given keyword. 209 * tomoyo_str_starts - Check whether the given string starts with the given keyword.
189 * 210 *
190 * @src: Pointer to pointer to the string. 211 * @src: Pointer to pointer to the string.