diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2011-06-26 10:16:36 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2011-06-28 19:31:19 -0400 |
commit | 0df7e8b8f1c25c10820bdc679555f2fbfb897ca0 (patch) | |
tree | 626a0304fceec0bbee93e43a24bc0f813fe230b7 | |
parent | b5bc60b4ce313b6dbb42e7d32915dcf0a07c2a68 (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.c | 43 | ||||
-rw-r--r-- | security/tomoyo/common.h | 78 | ||||
-rw-r--r-- | security/tomoyo/domain.c | 17 | ||||
-rw-r--r-- | security/tomoyo/file.c | 208 | ||||
-rw-r--r-- | security/tomoyo/gc.c | 127 | ||||
-rw-r--r-- | security/tomoyo/memory.c | 16 | ||||
-rw-r--r-- | security/tomoyo/mount.c | 31 | ||||
-rw-r--r-- | security/tomoyo/securityfs_if.c | 6 | ||||
-rw-r--r-- | security/tomoyo/util.c | 37 |
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, | |||
847 | static int tomoyo_write_domain(struct tomoyo_io_buffer *head) | 847 | static 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 | */ |
1885 | int tomoyo_read_control(struct file *file, char __user *buffer, | 1885 | int 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 | */ |
1917 | int tomoyo_write_control(struct file *file, const char __user *buffer, | 1916 | int 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 | */ |
1968 | int tomoyo_close_control(struct file *file) | 1966 | int 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. */ | ||
223 | struct 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. */ |
223 | struct tomoyo_request_info { | 229 | struct 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. */ |
283 | struct tomoyo_name { | 289 | struct 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. */ |
310 | struct tomoyo_group { | 310 | struct 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))); |
501 | void tomoyo_check_profile(void); | 502 | void tomoyo_check_profile(void); |
502 | int tomoyo_open_control(const u8 type, struct file *file); | 503 | int tomoyo_open_control(const u8 type, struct file *file); |
503 | int tomoyo_close_control(struct file *file); | 504 | int tomoyo_close_control(struct tomoyo_io_buffer *head); |
504 | int tomoyo_poll_control(struct file *file, poll_table *wait); | 505 | int tomoyo_poll_control(struct file *file, poll_table *wait); |
505 | int tomoyo_read_control(struct file *file, char __user *buffer, | 506 | int tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer, |
506 | const int buffer_len); | 507 | const int buffer_len); |
507 | int tomoyo_write_control(struct file *file, const char __user *buffer, | 508 | int tomoyo_write_control(struct tomoyo_io_buffer *head, |
508 | const int buffer_len); | 509 | const char __user *buffer, const int buffer_len); |
509 | bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r); | 510 | bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r); |
510 | void tomoyo_warn_oom(const char *function); | 511 | void tomoyo_warn_oom(const char *function); |
511 | const struct tomoyo_path_info * | 512 | const 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 | */ | ||
681 | static 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 | */ | ||
693 | static 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) | |||
721 | static inline void tomoyo_put_group(struct tomoyo_group *group) | 698 | static 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 | ||
750 | static 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, | |||
764 | static inline bool tomoyo_same_name_union | 735 | static 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 | */ | ||
69 | static 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 | */ | ||
52 | static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = { | 55 | static 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 | */ | ||
66 | static const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = { | 72 | static 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 | */ | ||
71 | static const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = { | 80 | static 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 | */ | ||
77 | static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = { | 90 | static 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 | */ | ||
88 | void tomoyo_put_name_union(struct tomoyo_name_union *ptr) | 108 | void 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 | */ | ||
98 | const struct tomoyo_path_info * | 122 | const struct tomoyo_path_info * |
99 | tomoyo_compare_name_union(const struct tomoyo_path_info *name, | 123 | tomoyo_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 | */ | ||
109 | void tomoyo_put_number_union(struct tomoyo_number_union *ptr) | 140 | void 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 | */ | ||
115 | bool tomoyo_compare_number_union(const unsigned long value, | 153 | bool 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 | */ | ||
123 | static void tomoyo_add_slash(struct tomoyo_path_info *buf) | 171 | static 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 | */ | ||
250 | static bool tomoyo_check_path_acl(struct tomoyo_request_info *r, | 310 | static 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 | */ | ||
264 | static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r, | 332 | static 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 | */ | ||
276 | static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r, | 352 | static 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 | */ | ||
287 | static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r, | 371 | static 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 | */ | ||
303 | static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a, | 395 | static 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 | */ | ||
367 | static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a, | 466 | static 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 | */ | ||
381 | static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a, | 486 | static 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 | */ |
413 | static int tomoyo_update_mkdev_acl(const u8 type, const char *filename, | 518 | static 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 | */ | ||
439 | static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a, | 552 | static 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 | */ | ||
449 | static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a, | 570 | static 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 | */ | ||
535 | static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a, | 664 | static 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 | */ | ||
547 | static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a, | 684 | static 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, | |||
575 | static int tomoyo_update_path_number_acl(const u8 type, const char *filename, | 712 | static 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 | */ |
739 | int tomoyo_mkdev_perm(const u8 operation, struct path *path, | 875 | int 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 | ||
14 | struct tomoyo_gc { | 14 | struct 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 | }; |
19 | static LIST_HEAD(tomoyo_gc_queue); | 19 | static LIST_HEAD(tomoyo_gc_queue); |
20 | static DEFINE_MUTEX(tomoyo_gc_mutex); | 20 | static 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 | */ | ||
23 | static bool tomoyo_add_to_gc(const int type, struct list_head *element) | 40 | static 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 | */ | ||
35 | static void tomoyo_del_transition_control(struct list_head *element) | 59 | static 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 | */ | ||
43 | static void tomoyo_del_aggregator(struct list_head *element) | 74 | static 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 | */ | ||
51 | static void tomoyo_del_manager(struct list_head *element) | 89 | static 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 | */ | ||
58 | static void tomoyo_del_acl(struct list_head *element) | 103 | static 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 | */ | ||
148 | static void tomoyo_del_name(struct list_head *element) | 200 | static 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 | */ | ||
154 | static void tomoyo_del_path_group(struct list_head *element) | 213 | static 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 | */ | ||
161 | static void tomoyo_del_group(struct list_head *element) | 227 | static 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 | */ | ||
168 | static void tomoyo_del_number_group(struct list_head *element) | 241 | static 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 | ||
174 | static 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 | */ | ||
255 | static 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 | */ | ||
198 | static void tomoyo_collect_entry(void) | 285 | static 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 | */ | ||
301 | static int tomoyo_gc_thread(void *unused) | 402 | static 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 | */ | ||
55 | static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r, | 63 | static 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 | */ | ||
235 | static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a, | 255 | static 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 | */ |
35 | static int tomoyo_release(struct inode *inode, struct file *file) | 35 | static 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) | |||
63 | static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count, | 63 | static 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, | |||
79 | static ssize_t tomoyo_write(struct file *file, const char __user *buf, | 79 | static 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 | */ | ||
191 | static 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 | */ | ||
203 | static 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. |