Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

security/tomoyo: Enable context analysis

Enable context analysis for security/tomoyo.

This demonstrates a larger conversion to use Clang's context
analysis. The benefit is additional static checking of locking rules,
along with better documentation.

Tomoyo makes use of several synchronization primitives, yet its clear
design made it relatively straightforward to enable context analysis.

One notable finding was:

security/tomoyo/gc.c:664:20: error: reading variable 'write_buf' requires holding mutex '&tomoyo_io_buffer::io_sem'
664 | is_write = head->write_buf != NULL;

For which Tetsuo writes:

"Good catch. This should be data_race(), for tomoyo_write_control()
might concurrently update head->write_buf from non-NULL to non-NULL
with head->io_sem held."

Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20251219154418.3592607-35-elver@google.com

authored by

Marco Elver and committed by
Peter Zijlstra
87335b61 8ec56d9a

+122 -49
+2
security/tomoyo/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 + CONTEXT_ANALYSIS := y 3 + 2 4 obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o 3 5 4 6 targets += builtin-policy.h
+48 -4
security/tomoyo/common.c
··· 268 268 */ 269 269 static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, 270 270 ...) 271 + __must_hold(&head->io_sem) 271 272 { 272 273 va_list args; 273 274 size_t len; ··· 417 416 * 418 417 * Returns nothing. 419 418 */ 420 - static void tomoyo_print_number_union_nospace 421 - (struct tomoyo_io_buffer *head, const struct tomoyo_number_union *ptr) 419 + static void 420 + tomoyo_print_number_union_nospace(struct tomoyo_io_buffer *head, const struct tomoyo_number_union *ptr) 421 + __must_hold(&head->io_sem) 422 422 { 423 423 if (ptr->group) { 424 424 tomoyo_set_string(head, "@"); ··· 468 466 */ 469 467 static void tomoyo_print_number_union(struct tomoyo_io_buffer *head, 470 468 const struct tomoyo_number_union *ptr) 469 + __must_hold(&head->io_sem) 471 470 { 472 471 tomoyo_set_space(head); 473 472 tomoyo_print_number_union_nospace(head, ptr); ··· 667 664 * Returns 0 on success, negative value otherwise. 668 665 */ 669 666 static int tomoyo_write_profile(struct tomoyo_io_buffer *head) 667 + __must_hold(&head->io_sem) 670 668 { 671 669 char *data = head->write_buf; 672 670 unsigned int i; ··· 723 719 * Caller prints functionality's name. 724 720 */ 725 721 static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config) 722 + __must_hold(&head->io_sem) 726 723 { 727 724 tomoyo_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n", 728 725 tomoyo_mode[config & 3], ··· 739 734 * Returns nothing. 740 735 */ 741 736 static void tomoyo_read_profile(struct tomoyo_io_buffer *head) 737 + __must_hold(&head->io_sem) 742 738 { 743 739 u8 index; 744 740 struct tomoyo_policy_namespace *ns = ··· 858 852 */ 859 853 static int tomoyo_update_manager_entry(const char *manager, 860 854 const bool is_delete) 855 + __must_hold_shared(&tomoyo_ss) 861 856 { 862 857 struct tomoyo_manager e = { }; 863 858 struct tomoyo_acl_param param = { ··· 890 883 * Caller holds tomoyo_read_lock(). 891 884 */ 892 885 static int tomoyo_write_manager(struct tomoyo_io_buffer *head) 886 + __must_hold_shared(&tomoyo_ss) 887 + __must_hold(&head->io_sem) 893 888 { 894 889 char *data = head->write_buf; 895 890 ··· 910 901 * Caller holds tomoyo_read_lock(). 911 902 */ 912 903 static void tomoyo_read_manager(struct tomoyo_io_buffer *head) 904 + __must_hold_shared(&tomoyo_ss) 913 905 { 914 906 if (head->r.eof) 915 907 return; ··· 937 927 * Caller holds tomoyo_read_lock(). 938 928 */ 939 929 static bool tomoyo_manager(void) 930 + __must_hold_shared(&tomoyo_ss) 940 931 { 941 932 struct tomoyo_manager *ptr; 942 933 const char *exe; ··· 992 981 */ 993 982 static bool tomoyo_select_domain(struct tomoyo_io_buffer *head, 994 983 const char *data) 984 + __must_hold_shared(&tomoyo_ss) 985 + __must_hold(&head->io_sem) 995 986 { 996 987 unsigned int pid; 997 988 struct tomoyo_domain_info *domain = NULL; ··· 1064 1051 * Caller holds tomoyo_read_lock(). 1065 1052 */ 1066 1053 static int tomoyo_write_task(struct tomoyo_acl_param *param) 1054 + __must_hold_shared(&tomoyo_ss) 1067 1055 { 1068 1056 int error = -EINVAL; 1069 1057 ··· 1093 1079 * Caller holds tomoyo_read_lock(). 1094 1080 */ 1095 1081 static int tomoyo_delete_domain(char *domainname) 1082 + __must_hold_shared(&tomoyo_ss) 1096 1083 { 1097 1084 struct tomoyo_domain_info *domain; 1098 1085 struct tomoyo_path_info name; ··· 1133 1118 static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns, 1134 1119 struct list_head *list, char *data, 1135 1120 const bool is_delete) 1121 + __must_hold_shared(&tomoyo_ss) 1136 1122 { 1137 1123 struct tomoyo_acl_param param = { 1138 1124 .ns = ns, ··· 1178 1162 * Caller holds tomoyo_read_lock(). 1179 1163 */ 1180 1164 static int tomoyo_write_domain(struct tomoyo_io_buffer *head) 1165 + __must_hold_shared(&tomoyo_ss) 1166 + __must_hold(&head->io_sem) 1181 1167 { 1182 1168 char *data = head->write_buf; 1183 1169 struct tomoyo_policy_namespace *ns; ··· 1241 1223 */ 1242 1224 static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, 1243 1225 const struct tomoyo_condition *cond) 1226 + __must_hold(&head->io_sem) 1244 1227 { 1245 1228 switch (head->r.cond_step) { 1246 1229 case 0: ··· 1383 1364 */ 1384 1365 static void tomoyo_set_group(struct tomoyo_io_buffer *head, 1385 1366 const char *category) 1367 + __must_hold(&head->io_sem) 1386 1368 { 1387 1369 if (head->type == TOMOYO_EXCEPTIONPOLICY) { 1388 1370 tomoyo_print_namespace(head); ··· 1403 1383 */ 1404 1384 static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, 1405 1385 struct tomoyo_acl_info *acl) 1386 + __must_hold(&head->io_sem) 1406 1387 { 1407 1388 const u8 acl_type = acl->type; 1408 1389 bool first = true; ··· 1609 1588 */ 1610 1589 static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head, 1611 1590 struct list_head *list) 1591 + __must_hold_shared(&tomoyo_ss) 1592 + __must_hold(&head->io_sem) 1612 1593 { 1613 1594 list_for_each_cookie(head->r.acl, list) { 1614 1595 struct tomoyo_acl_info *ptr = ··· 1631 1608 * Caller holds tomoyo_read_lock(). 1632 1609 */ 1633 1610 static void tomoyo_read_domain(struct tomoyo_io_buffer *head) 1611 + __must_hold_shared(&tomoyo_ss) 1612 + __must_hold(&head->io_sem) 1634 1613 { 1635 1614 if (head->r.eof) 1636 1615 return; ··· 1711 1686 * using read()/write() interface rather than sysctl() interface. 1712 1687 */ 1713 1688 static void tomoyo_read_pid(struct tomoyo_io_buffer *head) 1689 + __must_hold(&head->io_sem) 1714 1690 { 1715 1691 char *buf = head->write_buf; 1716 1692 bool global_pid = false; ··· 1772 1746 * Caller holds tomoyo_read_lock(). 1773 1747 */ 1774 1748 static int tomoyo_write_exception(struct tomoyo_io_buffer *head) 1749 + __must_hold_shared(&tomoyo_ss) 1750 + __must_hold(&head->io_sem) 1775 1751 { 1776 1752 const bool is_delete = head->w.is_delete; 1777 1753 struct tomoyo_acl_param param = { ··· 1815 1787 * Caller holds tomoyo_read_lock(). 1816 1788 */ 1817 1789 static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) 1790 + __must_hold_shared(&tomoyo_ss) 1791 + __must_hold(&head->io_sem) 1818 1792 { 1819 1793 struct tomoyo_policy_namespace *ns = 1820 1794 container_of(head->r.ns, typeof(*ns), namespace_list); ··· 1876 1846 * Caller holds tomoyo_read_lock(). 1877 1847 */ 1878 1848 static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) 1849 + __must_hold_shared(&tomoyo_ss) 1879 1850 { 1880 1851 struct tomoyo_policy_namespace *ns = 1881 1852 container_of(head->r.ns, typeof(*ns), namespace_list); ··· 1937 1906 * Caller holds tomoyo_read_lock(). 1938 1907 */ 1939 1908 static void tomoyo_read_exception(struct tomoyo_io_buffer *head) 1909 + __must_hold_shared(&tomoyo_ss) 1910 + __must_hold(&head->io_sem) 1940 1911 { 1941 1912 struct tomoyo_policy_namespace *ns = 1942 1913 container_of(head->r.ns, typeof(*ns), namespace_list); ··· 2130 2097 * Returns nothing. 2131 2098 */ 2132 2099 static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header) 2100 + __must_hold_shared(&tomoyo_ss) 2133 2101 { 2134 2102 char *buffer; 2135 2103 char *realpath = NULL; ··· 2335 2301 * @head: Pointer to "struct tomoyo_io_buffer". 2336 2302 */ 2337 2303 static void tomoyo_read_query(struct tomoyo_io_buffer *head) 2304 + __must_hold(&head->io_sem) 2338 2305 { 2339 2306 struct list_head *tmp; 2340 2307 unsigned int pos = 0; ··· 2397 2362 * Returns 0 on success, -EINVAL otherwise. 2398 2363 */ 2399 2364 static int tomoyo_write_answer(struct tomoyo_io_buffer *head) 2365 + __must_hold(&head->io_sem) 2400 2366 { 2401 2367 char *data = head->write_buf; 2402 2368 struct list_head *tmp; ··· 2437 2401 * Returns version information. 2438 2402 */ 2439 2403 static void tomoyo_read_version(struct tomoyo_io_buffer *head) 2404 + __must_hold(&head->io_sem) 2440 2405 { 2441 2406 if (!head->r.eof) { 2442 2407 tomoyo_io_printf(head, "2.6.0"); ··· 2486 2449 * Returns nothing. 2487 2450 */ 2488 2451 static void tomoyo_read_stat(struct tomoyo_io_buffer *head) 2452 + __must_hold(&head->io_sem) 2489 2453 { 2490 2454 u8 i; 2491 2455 unsigned int total = 0; ··· 2531 2493 * Returns 0. 2532 2494 */ 2533 2495 static int tomoyo_write_stat(struct tomoyo_io_buffer *head) 2496 + __must_hold(&head->io_sem) 2534 2497 { 2535 2498 char *data = head->write_buf; 2536 2499 u8 i; ··· 2756 2717 * Caller holds tomoyo_read_lock(). 2757 2718 */ 2758 2719 static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line) 2720 + __must_hold_shared(&tomoyo_ss) 2721 + __must_hold(&head->io_sem) 2759 2722 { 2760 2723 /* Delete request? */ 2761 2724 head->w.is_delete = !strncmp(line, "delete ", 7); ··· 3010 2969 break; 3011 2970 *end = '\0'; 3012 2971 tomoyo_normalize_line(start); 3013 - head.write_buf = start; 3014 - tomoyo_parse_policy(&head, start); 2972 + /* head is stack-local and not shared. */ 2973 + context_unsafe( 2974 + head.write_buf = start; 2975 + tomoyo_parse_policy(&head, start); 2976 + ); 3015 2977 start = end + 1; 3016 2978 } 3017 2979 }
+40 -37
security/tomoyo/common.h
··· 827 827 bool is_delete; 828 828 } w; 829 829 /* Buffer for reading. */ 830 - char *read_buf; 830 + char *read_buf __guarded_by(&io_sem); 831 831 /* Size of read buffer. */ 832 - size_t readbuf_size; 832 + size_t readbuf_size __guarded_by(&io_sem); 833 833 /* Buffer for writing. */ 834 - char *write_buf; 834 + char *write_buf __guarded_by(&io_sem); 835 835 /* Size of write buffer. */ 836 - size_t writebuf_size; 836 + size_t writebuf_size __guarded_by(&io_sem); 837 837 /* Type of this interface. */ 838 838 enum tomoyo_securityfs_interface_index type; 839 839 /* Users counter protected by tomoyo_io_buffer_list_lock. */ ··· 922 922 struct tomoyo_domain_info *old_domain_info; 923 923 }; 924 924 925 + /********** External variable definitions. **********/ 926 + 927 + extern bool tomoyo_policy_loaded; 928 + extern int tomoyo_enabled; 929 + extern const char * const tomoyo_condition_keyword 930 + [TOMOYO_MAX_CONDITION_KEYWORD]; 931 + extern const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS]; 932 + extern const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX 933 + + TOMOYO_MAX_MAC_CATEGORY_INDEX]; 934 + extern const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE]; 935 + extern const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION]; 936 + extern const char * const tomoyo_proto_keyword[TOMOYO_SOCK_MAX]; 937 + extern const char * const tomoyo_socket_keyword[TOMOYO_MAX_NETWORK_OPERATION]; 938 + extern const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX]; 939 + extern const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION]; 940 + extern const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION]; 941 + extern const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION]; 942 + extern struct list_head tomoyo_condition_list; 943 + extern struct list_head tomoyo_domain_list; 944 + extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 945 + extern struct list_head tomoyo_namespace_list; 946 + extern struct mutex tomoyo_policy_lock; 947 + extern struct srcu_struct tomoyo_ss; 948 + extern struct tomoyo_domain_info tomoyo_kernel_domain; 949 + extern struct tomoyo_policy_namespace tomoyo_kernel_namespace; 950 + extern unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT]; 951 + extern unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT]; 952 + extern struct lsm_blob_sizes tomoyo_blob_sizes; 953 + 925 954 /********** Function prototypes. **********/ 926 955 927 956 int tomoyo_interface_init(void); ··· 1000 971 int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, 1001 972 const struct path *path, const int flag); 1002 973 void tomoyo_close_control(struct tomoyo_io_buffer *head); 1003 - int tomoyo_env_perm(struct tomoyo_request_info *r, const char *env); 974 + int tomoyo_env_perm(struct tomoyo_request_info *r, const char *env) __must_hold_shared(&tomoyo_ss); 1004 975 int tomoyo_execute_permission(struct tomoyo_request_info *r, 1005 - const struct tomoyo_path_info *filename); 1006 - int tomoyo_find_next_domain(struct linux_binprm *bprm); 976 + const struct tomoyo_path_info *filename) __must_hold_shared(&tomoyo_ss); 977 + int tomoyo_find_next_domain(struct linux_binprm *bprm) __must_hold_shared(&tomoyo_ss); 1007 978 int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile, 1008 979 const u8 index); 1009 980 int tomoyo_init_request_info(struct tomoyo_request_info *r, ··· 1031 1002 int tomoyo_socket_sendmsg_permission(struct socket *sock, struct msghdr *msg, 1032 1003 int size); 1033 1004 int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) 1005 + __must_hold_shared(&tomoyo_ss) 1034 1006 __printf(2, 3); 1035 1007 int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, 1036 1008 struct tomoyo_acl_param *param, ··· 1091 1061 const unsigned long value, const u8 type); 1092 1062 void tomoyo_put_name_union(struct tomoyo_name_union *ptr); 1093 1063 void tomoyo_put_number_union(struct tomoyo_number_union *ptr); 1094 - void tomoyo_read_log(struct tomoyo_io_buffer *head); 1064 + void tomoyo_read_log(struct tomoyo_io_buffer *head) __must_hold(&head->io_sem); 1095 1065 void tomoyo_update_stat(const u8 index); 1096 1066 void tomoyo_warn_oom(const char *function); 1097 1067 void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...) 1098 1068 __printf(2, 3); 1099 1069 void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt, 1100 1070 va_list args) __printf(3, 0); 1101 - 1102 - /********** External variable definitions. **********/ 1103 - 1104 - extern bool tomoyo_policy_loaded; 1105 - extern int tomoyo_enabled; 1106 - extern const char * const tomoyo_condition_keyword 1107 - [TOMOYO_MAX_CONDITION_KEYWORD]; 1108 - extern const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS]; 1109 - extern const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX 1110 - + TOMOYO_MAX_MAC_CATEGORY_INDEX]; 1111 - extern const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE]; 1112 - extern const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION]; 1113 - extern const char * const tomoyo_proto_keyword[TOMOYO_SOCK_MAX]; 1114 - extern const char * const tomoyo_socket_keyword[TOMOYO_MAX_NETWORK_OPERATION]; 1115 - extern const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX]; 1116 - extern const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION]; 1117 - extern const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION]; 1118 - extern const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION]; 1119 - extern struct list_head tomoyo_condition_list; 1120 - extern struct list_head tomoyo_domain_list; 1121 - extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 1122 - extern struct list_head tomoyo_namespace_list; 1123 - extern struct mutex tomoyo_policy_lock; 1124 - extern struct srcu_struct tomoyo_ss; 1125 - extern struct tomoyo_domain_info tomoyo_kernel_domain; 1126 - extern struct tomoyo_policy_namespace tomoyo_kernel_namespace; 1127 - extern unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT]; 1128 - extern unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT]; 1129 - extern struct lsm_blob_sizes tomoyo_blob_sizes; 1130 1071 1131 1072 /********** Inlined functions. **********/ 1132 1073 ··· 1107 1106 * Returns index number for tomoyo_read_unlock(). 1108 1107 */ 1109 1108 static inline int tomoyo_read_lock(void) 1109 + __acquires_shared(&tomoyo_ss) 1110 1110 { 1111 1111 return srcu_read_lock(&tomoyo_ss); 1112 1112 } ··· 1120 1118 * Returns nothing. 1121 1119 */ 1122 1120 static inline void tomoyo_read_unlock(int idx) 1121 + __releases_shared(&tomoyo_ss) 1123 1122 { 1124 1123 srcu_read_unlock(&tomoyo_ss, idx); 1125 1124 }
+1
security/tomoyo/domain.c
··· 611 611 * Returns 0 on success, negative value otherwise. 612 612 */ 613 613 static int tomoyo_environ(struct tomoyo_execve *ee) 614 + __must_hold_shared(&tomoyo_ss) 614 615 { 615 616 struct tomoyo_request_info *r = &ee->r; 616 617 struct linux_binprm *bprm = ee->bprm;
+1
security/tomoyo/environ.c
··· 32 32 * Returns 0 on success, negative value otherwise. 33 33 */ 34 34 static int tomoyo_audit_env_log(struct tomoyo_request_info *r) 35 + __must_hold_shared(&tomoyo_ss) 35 36 { 36 37 return tomoyo_supervisor(r, "misc env %s\n", 37 38 r->param.environ.name->name);
+5
security/tomoyo/file.c
··· 164 164 * Returns 0 on success, negative value otherwise. 165 165 */ 166 166 static int tomoyo_audit_path_log(struct tomoyo_request_info *r) 167 + __must_hold_shared(&tomoyo_ss) 167 168 { 168 169 return tomoyo_supervisor(r, "file %s %s\n", tomoyo_path_keyword 169 170 [r->param.path.operation], ··· 179 178 * Returns 0 on success, negative value otherwise. 180 179 */ 181 180 static int tomoyo_audit_path2_log(struct tomoyo_request_info *r) 181 + __must_hold_shared(&tomoyo_ss) 182 182 { 183 183 return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords 184 184 [tomoyo_pp2mac[r->param.path2.operation]], ··· 195 193 * Returns 0 on success, negative value otherwise. 196 194 */ 197 195 static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r) 196 + __must_hold_shared(&tomoyo_ss) 198 197 { 199 198 return tomoyo_supervisor(r, "file %s %s 0%o %u %u\n", 200 199 tomoyo_mac_keywords ··· 213 210 * Returns 0 on success, negative value otherwise. 214 211 */ 215 212 static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r) 213 + __must_hold_shared(&tomoyo_ss) 216 214 { 217 215 const u8 type = r->param.path_number.operation; 218 216 u8 radix; ··· 576 572 */ 577 573 static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, 578 574 const struct tomoyo_path_info *filename) 575 + __must_hold_shared(&tomoyo_ss) 579 576 { 580 577 int error; 581 578
+20 -8
security/tomoyo/gc.c
··· 23 23 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= ksize(ptr); 24 24 kfree(ptr); 25 25 } 26 - 27 - /* The list for "struct tomoyo_io_buffer". */ 28 - static LIST_HEAD(tomoyo_io_buffer_list); 29 26 /* Lock for protecting tomoyo_io_buffer_list. */ 30 27 static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock); 28 + /* The list for "struct tomoyo_io_buffer". */ 29 + static __guarded_by(&tomoyo_io_buffer_list_lock) LIST_HEAD(tomoyo_io_buffer_list); 31 30 32 31 /** 33 32 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not. ··· 384 385 */ 385 386 static void tomoyo_try_to_gc(const enum tomoyo_policy_id type, 386 387 struct list_head *element) 388 + __must_hold(&tomoyo_policy_lock) 387 389 { 388 390 /* 389 391 * __list_del_entry() guarantees that the list element became no longer ··· 484 484 */ 485 485 static void tomoyo_collect_member(const enum tomoyo_policy_id id, 486 486 struct list_head *member_list) 487 + __must_hold(&tomoyo_policy_lock) 487 488 { 488 489 struct tomoyo_acl_head *member; 489 490 struct tomoyo_acl_head *tmp; ··· 505 504 * Returns nothing. 506 505 */ 507 506 static void tomoyo_collect_acl(struct list_head *list) 507 + __must_hold(&tomoyo_policy_lock) 508 508 { 509 509 struct tomoyo_acl_info *acl; 510 510 struct tomoyo_acl_info *tmp; ··· 629 627 if (head->users) 630 628 continue; 631 629 list_del(&head->list); 632 - kfree(head->read_buf); 633 - kfree(head->write_buf); 630 + /* Safe destruction because no users are left. */ 631 + context_unsafe( 632 + kfree(head->read_buf); 633 + kfree(head->write_buf); 634 + ); 634 635 kfree(head); 635 636 } 636 637 spin_unlock(&tomoyo_io_buffer_list_lock); ··· 661 656 head->users = 1; 662 657 list_add(&head->list, &tomoyo_io_buffer_list); 663 658 } else { 664 - is_write = head->write_buf != NULL; 659 + /* 660 + * tomoyo_write_control() can concurrently update write_buf from 661 + * a non-NULL to new non-NULL pointer with io_sem held. 662 + */ 663 + is_write = data_race(head->write_buf != NULL); 665 664 if (!--head->users) { 666 665 list_del(&head->list); 667 - kfree(head->read_buf); 668 - kfree(head->write_buf); 666 + /* Safe destruction because no users are left. */ 667 + context_unsafe( 668 + kfree(head->read_buf); 669 + kfree(head->write_buf); 670 + ); 669 671 kfree(head); 670 672 } 671 673 }
+2
security/tomoyo/mount.c
··· 28 28 * Returns 0 on success, negative value otherwise. 29 29 */ 30 30 static int tomoyo_audit_mount_log(struct tomoyo_request_info *r) 31 + __must_hold_shared(&tomoyo_ss) 31 32 { 32 33 return tomoyo_supervisor(r, "file mount %s %s %s 0x%lX\n", 33 34 r->param.mount.dev->name, ··· 79 78 const char *dev_name, 80 79 const struct path *dir, const char *type, 81 80 unsigned long flags) 81 + __must_hold_shared(&tomoyo_ss) 82 82 { 83 83 struct tomoyo_obj_info obj = { }; 84 84 struct path path;
+3
security/tomoyo/network.c
··· 363 363 static int tomoyo_audit_net_log(struct tomoyo_request_info *r, 364 364 const char *family, const u8 protocol, 365 365 const u8 operation, const char *address) 366 + __must_hold_shared(&tomoyo_ss) 366 367 { 367 368 return tomoyo_supervisor(r, "network %s %s %s %s\n", family, 368 369 tomoyo_proto_keyword[protocol], ··· 378 377 * Returns 0 on success, negative value otherwise. 379 378 */ 380 379 static int tomoyo_audit_inet_log(struct tomoyo_request_info *r) 380 + __must_hold_shared(&tomoyo_ss) 381 381 { 382 382 char buf[128]; 383 383 int len; ··· 404 402 * Returns 0 on success, negative value otherwise. 405 403 */ 406 404 static int tomoyo_audit_unix_log(struct tomoyo_request_info *r) 405 + __must_hold_shared(&tomoyo_ss) 407 406 { 408 407 return tomoyo_audit_net_log(r, "unix", r->param.unix_network.protocol, 409 408 r->param.unix_network.operation,