1 // SPDX-License-Identifier: GPL-2.0 << 2 /* 1 /* 3 * security/tomoyo/gc.c 2 * security/tomoyo/gc.c 4 * 3 * 5 * Copyright (C) 2005-2011 NTT DATA CORPORATI 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION 6 */ 5 */ 7 6 8 #include "common.h" 7 #include "common.h" 9 #include <linux/kthread.h> 8 #include <linux/kthread.h> 10 #include <linux/slab.h> 9 #include <linux/slab.h> 11 10 12 /** 11 /** 13 * tomoyo_memory_free - Free memory for elemen 12 * tomoyo_memory_free - Free memory for elements. 14 * 13 * 15 * @ptr: Pointer to allocated memory. 14 * @ptr: Pointer to allocated memory. 16 * 15 * 17 * Returns nothing. 16 * Returns nothing. 18 * 17 * 19 * Caller holds tomoyo_policy_lock mutex. 18 * Caller holds tomoyo_policy_lock mutex. 20 */ 19 */ 21 static inline void tomoyo_memory_free(void *pt 20 static inline void tomoyo_memory_free(void *ptr) 22 { 21 { 23 tomoyo_memory_used[TOMOYO_MEMORY_POLIC 22 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= ksize(ptr); 24 kfree(ptr); 23 kfree(ptr); 25 } 24 } 26 25 27 /* The list for "struct tomoyo_io_buffer". */ 26 /* The list for "struct tomoyo_io_buffer". */ 28 static LIST_HEAD(tomoyo_io_buffer_list); 27 static LIST_HEAD(tomoyo_io_buffer_list); 29 /* Lock for protecting tomoyo_io_buffer_list. 28 /* Lock for protecting tomoyo_io_buffer_list. */ 30 static DEFINE_SPINLOCK(tomoyo_io_buffer_list_l 29 static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock); 31 30 32 /** 31 /** 33 * tomoyo_struct_used_by_io_buffer - Check whe 32 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not. 34 * 33 * 35 * @element: Pointer to "struct list_head". 34 * @element: Pointer to "struct list_head". 36 * 35 * 37 * Returns true if @element is used by /sys/ke 36 * Returns true if @element is used by /sys/kernel/security/tomoyo/ users, 38 * false otherwise. 37 * false otherwise. 39 */ 38 */ 40 static bool tomoyo_struct_used_by_io_buffer(co 39 static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element) 41 { 40 { 42 struct tomoyo_io_buffer *head; 41 struct tomoyo_io_buffer *head; 43 bool in_use = false; 42 bool in_use = false; 44 43 45 spin_lock(&tomoyo_io_buffer_list_lock) 44 spin_lock(&tomoyo_io_buffer_list_lock); 46 list_for_each_entry(head, &tomoyo_io_b 45 list_for_each_entry(head, &tomoyo_io_buffer_list, list) { 47 head->users++; 46 head->users++; 48 spin_unlock(&tomoyo_io_buffer_ 47 spin_unlock(&tomoyo_io_buffer_list_lock); 49 mutex_lock(&head->io_sem); 48 mutex_lock(&head->io_sem); 50 if (head->r.domain == element 49 if (head->r.domain == element || head->r.group == element || 51 head->r.acl == element || 50 head->r.acl == element || &head->w.domain->list == element) 52 in_use = true; 51 in_use = true; 53 mutex_unlock(&head->io_sem); 52 mutex_unlock(&head->io_sem); 54 spin_lock(&tomoyo_io_buffer_li 53 spin_lock(&tomoyo_io_buffer_list_lock); 55 head->users--; 54 head->users--; 56 if (in_use) 55 if (in_use) 57 break; 56 break; 58 } 57 } 59 spin_unlock(&tomoyo_io_buffer_list_loc 58 spin_unlock(&tomoyo_io_buffer_list_lock); 60 return in_use; 59 return in_use; 61 } 60 } 62 61 63 /** 62 /** 64 * tomoyo_name_used_by_io_buffer - Check wheth 63 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not. 65 * 64 * 66 * @string: String to check. 65 * @string: String to check. 67 * 66 * 68 * Returns true if @string is used by /sys/ker 67 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users, 69 * false otherwise. 68 * false otherwise. 70 */ 69 */ 71 static bool tomoyo_name_used_by_io_buffer(cons 70 static bool tomoyo_name_used_by_io_buffer(const char *string) 72 { 71 { 73 struct tomoyo_io_buffer *head; 72 struct tomoyo_io_buffer *head; 74 const size_t size = strlen(string) + 1 73 const size_t size = strlen(string) + 1; 75 bool in_use = false; 74 bool in_use = false; 76 75 77 spin_lock(&tomoyo_io_buffer_list_lock) 76 spin_lock(&tomoyo_io_buffer_list_lock); 78 list_for_each_entry(head, &tomoyo_io_b 77 list_for_each_entry(head, &tomoyo_io_buffer_list, list) { 79 int i; 78 int i; 80 << 81 head->users++; 79 head->users++; 82 spin_unlock(&tomoyo_io_buffer_ 80 spin_unlock(&tomoyo_io_buffer_list_lock); 83 mutex_lock(&head->io_sem); 81 mutex_lock(&head->io_sem); 84 for (i = 0; i < TOMOYO_MAX_IO_ 82 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) { 85 const char *w = head-> 83 const char *w = head->r.w[i]; 86 << 87 if (w < string || w > 84 if (w < string || w > string + size) 88 continue; 85 continue; 89 in_use = true; 86 in_use = true; 90 break; 87 break; 91 } 88 } 92 mutex_unlock(&head->io_sem); 89 mutex_unlock(&head->io_sem); 93 spin_lock(&tomoyo_io_buffer_li 90 spin_lock(&tomoyo_io_buffer_list_lock); 94 head->users--; 91 head->users--; 95 if (in_use) 92 if (in_use) 96 break; 93 break; 97 } 94 } 98 spin_unlock(&tomoyo_io_buffer_list_loc 95 spin_unlock(&tomoyo_io_buffer_list_lock); 99 return in_use; 96 return in_use; 100 } 97 } 101 98 102 /** 99 /** 103 * tomoyo_del_transition_control - Delete memb 100 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control". 104 * 101 * 105 * @element: Pointer to "struct list_head". 102 * @element: Pointer to "struct list_head". 106 * 103 * 107 * Returns nothing. 104 * Returns nothing. 108 */ 105 */ 109 static inline void tomoyo_del_transition_contr 106 static inline void tomoyo_del_transition_control(struct list_head *element) 110 { 107 { 111 struct tomoyo_transition_control *ptr 108 struct tomoyo_transition_control *ptr = 112 container_of(element, typeof(* 109 container_of(element, typeof(*ptr), head.list); 113 << 114 tomoyo_put_name(ptr->domainname); 110 tomoyo_put_name(ptr->domainname); 115 tomoyo_put_name(ptr->program); 111 tomoyo_put_name(ptr->program); 116 } 112 } 117 113 118 /** 114 /** 119 * tomoyo_del_aggregator - Delete members in " 115 * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator". 120 * 116 * 121 * @element: Pointer to "struct list_head". 117 * @element: Pointer to "struct list_head". 122 * 118 * 123 * Returns nothing. 119 * Returns nothing. 124 */ 120 */ 125 static inline void tomoyo_del_aggregator(struc 121 static inline void tomoyo_del_aggregator(struct list_head *element) 126 { 122 { 127 struct tomoyo_aggregator *ptr = 123 struct tomoyo_aggregator *ptr = 128 container_of(element, typeof(* 124 container_of(element, typeof(*ptr), head.list); 129 << 130 tomoyo_put_name(ptr->original_name); 125 tomoyo_put_name(ptr->original_name); 131 tomoyo_put_name(ptr->aggregated_name); 126 tomoyo_put_name(ptr->aggregated_name); 132 } 127 } 133 128 134 /** 129 /** 135 * tomoyo_del_manager - Delete members in "str 130 * tomoyo_del_manager - Delete members in "struct tomoyo_manager". 136 * 131 * 137 * @element: Pointer to "struct list_head". 132 * @element: Pointer to "struct list_head". 138 * 133 * 139 * Returns nothing. 134 * Returns nothing. 140 */ 135 */ 141 static inline void tomoyo_del_manager(struct l 136 static inline void tomoyo_del_manager(struct list_head *element) 142 { 137 { 143 struct tomoyo_manager *ptr = 138 struct tomoyo_manager *ptr = 144 container_of(element, typeof(* 139 container_of(element, typeof(*ptr), head.list); 145 << 146 tomoyo_put_name(ptr->manager); 140 tomoyo_put_name(ptr->manager); 147 } 141 } 148 142 149 /** 143 /** 150 * tomoyo_del_acl - Delete members in "struct 144 * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info". 151 * 145 * 152 * @element: Pointer to "struct list_head". 146 * @element: Pointer to "struct list_head". 153 * 147 * 154 * Returns nothing. 148 * Returns nothing. 155 */ 149 */ 156 static void tomoyo_del_acl(struct list_head *e 150 static void tomoyo_del_acl(struct list_head *element) 157 { 151 { 158 struct tomoyo_acl_info *acl = 152 struct tomoyo_acl_info *acl = 159 container_of(element, typeof(* 153 container_of(element, typeof(*acl), list); 160 << 161 tomoyo_put_condition(acl->cond); 154 tomoyo_put_condition(acl->cond); 162 switch (acl->type) { 155 switch (acl->type) { 163 case TOMOYO_TYPE_PATH_ACL: 156 case TOMOYO_TYPE_PATH_ACL: 164 { 157 { 165 struct tomoyo_path_acl 158 struct tomoyo_path_acl *entry 166 = container_of 159 = container_of(acl, typeof(*entry), head); 167 tomoyo_put_name_union( 160 tomoyo_put_name_union(&entry->name); 168 } 161 } 169 break; 162 break; 170 case TOMOYO_TYPE_PATH2_ACL: 163 case TOMOYO_TYPE_PATH2_ACL: 171 { 164 { 172 struct tomoyo_path2_ac 165 struct tomoyo_path2_acl *entry 173 = container_of 166 = container_of(acl, typeof(*entry), head); 174 tomoyo_put_name_union( 167 tomoyo_put_name_union(&entry->name1); 175 tomoyo_put_name_union( 168 tomoyo_put_name_union(&entry->name2); 176 } 169 } 177 break; 170 break; 178 case TOMOYO_TYPE_PATH_NUMBER_ACL: 171 case TOMOYO_TYPE_PATH_NUMBER_ACL: 179 { 172 { 180 struct tomoyo_path_num 173 struct tomoyo_path_number_acl *entry 181 = container_of 174 = container_of(acl, typeof(*entry), head); 182 tomoyo_put_name_union( 175 tomoyo_put_name_union(&entry->name); 183 tomoyo_put_number_unio 176 tomoyo_put_number_union(&entry->number); 184 } 177 } 185 break; 178 break; 186 case TOMOYO_TYPE_MKDEV_ACL: 179 case TOMOYO_TYPE_MKDEV_ACL: 187 { 180 { 188 struct tomoyo_mkdev_ac 181 struct tomoyo_mkdev_acl *entry 189 = container_of 182 = container_of(acl, typeof(*entry), head); 190 tomoyo_put_name_union( 183 tomoyo_put_name_union(&entry->name); 191 tomoyo_put_number_unio 184 tomoyo_put_number_union(&entry->mode); 192 tomoyo_put_number_unio 185 tomoyo_put_number_union(&entry->major); 193 tomoyo_put_number_unio 186 tomoyo_put_number_union(&entry->minor); 194 } 187 } 195 break; 188 break; 196 case TOMOYO_TYPE_MOUNT_ACL: 189 case TOMOYO_TYPE_MOUNT_ACL: 197 { 190 { 198 struct tomoyo_mount_ac 191 struct tomoyo_mount_acl *entry 199 = container_of 192 = container_of(acl, typeof(*entry), head); 200 tomoyo_put_name_union( 193 tomoyo_put_name_union(&entry->dev_name); 201 tomoyo_put_name_union( 194 tomoyo_put_name_union(&entry->dir_name); 202 tomoyo_put_name_union( 195 tomoyo_put_name_union(&entry->fs_type); 203 tomoyo_put_number_unio 196 tomoyo_put_number_union(&entry->flags); 204 } 197 } 205 break; 198 break; 206 case TOMOYO_TYPE_ENV_ACL: 199 case TOMOYO_TYPE_ENV_ACL: 207 { 200 { 208 struct tomoyo_env_acl 201 struct tomoyo_env_acl *entry = 209 container_of(a 202 container_of(acl, typeof(*entry), head); 210 203 211 tomoyo_put_name(entry- 204 tomoyo_put_name(entry->env); 212 } 205 } 213 break; 206 break; 214 case TOMOYO_TYPE_INET_ACL: 207 case TOMOYO_TYPE_INET_ACL: 215 { 208 { 216 struct tomoyo_inet_acl 209 struct tomoyo_inet_acl *entry = 217 container_of(a 210 container_of(acl, typeof(*entry), head); 218 211 219 tomoyo_put_group(entry 212 tomoyo_put_group(entry->address.group); 220 tomoyo_put_number_unio 213 tomoyo_put_number_union(&entry->port); 221 } 214 } 222 break; 215 break; 223 case TOMOYO_TYPE_UNIX_ACL: 216 case TOMOYO_TYPE_UNIX_ACL: 224 { 217 { 225 struct tomoyo_unix_acl 218 struct tomoyo_unix_acl *entry = 226 container_of(a 219 container_of(acl, typeof(*entry), head); 227 220 228 tomoyo_put_name_union( 221 tomoyo_put_name_union(&entry->name); 229 } 222 } 230 break; 223 break; 231 case TOMOYO_TYPE_MANUAL_TASK_ACL: 224 case TOMOYO_TYPE_MANUAL_TASK_ACL: 232 { 225 { 233 struct tomoyo_task_acl 226 struct tomoyo_task_acl *entry = 234 container_of(a 227 container_of(acl, typeof(*entry), head); 235 << 236 tomoyo_put_name(entry- 228 tomoyo_put_name(entry->domainname); 237 } 229 } 238 break; 230 break; 239 } 231 } 240 } 232 } 241 233 242 /** 234 /** 243 * tomoyo_del_domain - Delete members in "stru 235 * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info". 244 * 236 * 245 * @element: Pointer to "struct list_head". 237 * @element: Pointer to "struct list_head". 246 * 238 * 247 * Returns nothing. 239 * Returns nothing. 248 * 240 * 249 * Caller holds tomoyo_policy_lock mutex. 241 * Caller holds tomoyo_policy_lock mutex. 250 */ 242 */ 251 static inline void tomoyo_del_domain(struct li 243 static inline void tomoyo_del_domain(struct list_head *element) 252 { 244 { 253 struct tomoyo_domain_info *domain = 245 struct tomoyo_domain_info *domain = 254 container_of(element, typeof(* 246 container_of(element, typeof(*domain), list); 255 struct tomoyo_acl_info *acl; 247 struct tomoyo_acl_info *acl; 256 struct tomoyo_acl_info *tmp; 248 struct tomoyo_acl_info *tmp; 257 << 258 /* 249 /* 259 * Since this domain is referenced fro 250 * Since this domain is referenced from neither 260 * "struct tomoyo_io_buffer" nor "stru 251 * "struct tomoyo_io_buffer" nor "struct cred"->security, we can delete 261 * elements without checking for is_de 252 * elements without checking for is_deleted flag. 262 */ 253 */ 263 list_for_each_entry_safe(acl, tmp, &do 254 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) { 264 tomoyo_del_acl(&acl->list); 255 tomoyo_del_acl(&acl->list); 265 tomoyo_memory_free(acl); 256 tomoyo_memory_free(acl); 266 } 257 } 267 tomoyo_put_name(domain->domainname); 258 tomoyo_put_name(domain->domainname); 268 } 259 } 269 260 270 /** 261 /** 271 * tomoyo_del_condition - Delete members in "s 262 * tomoyo_del_condition - Delete members in "struct tomoyo_condition". 272 * 263 * 273 * @element: Pointer to "struct list_head". 264 * @element: Pointer to "struct list_head". 274 * 265 * 275 * Returns nothing. 266 * Returns nothing. 276 */ 267 */ 277 void tomoyo_del_condition(struct list_head *el 268 void tomoyo_del_condition(struct list_head *element) 278 { 269 { 279 struct tomoyo_condition *cond = contai 270 struct tomoyo_condition *cond = container_of(element, typeof(*cond), 280 271 head.list); 281 const u16 condc = cond->condc; 272 const u16 condc = cond->condc; 282 const u16 numbers_count = cond->number 273 const u16 numbers_count = cond->numbers_count; 283 const u16 names_count = cond->names_co 274 const u16 names_count = cond->names_count; 284 const u16 argc = cond->argc; 275 const u16 argc = cond->argc; 285 const u16 envc = cond->envc; 276 const u16 envc = cond->envc; 286 unsigned int i; 277 unsigned int i; 287 const struct tomoyo_condition_element 278 const struct tomoyo_condition_element *condp 288 = (const struct tomoyo_conditi 279 = (const struct tomoyo_condition_element *) (cond + 1); 289 struct tomoyo_number_union *numbers_p 280 struct tomoyo_number_union *numbers_p 290 = (struct tomoyo_number_union 281 = (struct tomoyo_number_union *) (condp + condc); 291 struct tomoyo_name_union *names_p 282 struct tomoyo_name_union *names_p 292 = (struct tomoyo_name_union *) 283 = (struct tomoyo_name_union *) (numbers_p + numbers_count); 293 const struct tomoyo_argv *argv 284 const struct tomoyo_argv *argv 294 = (const struct tomoyo_argv *) 285 = (const struct tomoyo_argv *) (names_p + names_count); 295 const struct tomoyo_envp *envp 286 const struct tomoyo_envp *envp 296 = (const struct tomoyo_envp *) 287 = (const struct tomoyo_envp *) (argv + argc); 297 << 298 for (i = 0; i < numbers_count; i++) 288 for (i = 0; i < numbers_count; i++) 299 tomoyo_put_number_union(number 289 tomoyo_put_number_union(numbers_p++); 300 for (i = 0; i < names_count; i++) 290 for (i = 0; i < names_count; i++) 301 tomoyo_put_name_union(names_p+ 291 tomoyo_put_name_union(names_p++); 302 for (i = 0; i < argc; argv++, i++) 292 for (i = 0; i < argc; argv++, i++) 303 tomoyo_put_name(argv->value); 293 tomoyo_put_name(argv->value); 304 for (i = 0; i < envc; envp++, i++) { 294 for (i = 0; i < envc; envp++, i++) { 305 tomoyo_put_name(envp->name); 295 tomoyo_put_name(envp->name); 306 tomoyo_put_name(envp->value); 296 tomoyo_put_name(envp->value); 307 } 297 } 308 } 298 } 309 299 310 /** 300 /** 311 * tomoyo_del_name - Delete members in "struct 301 * tomoyo_del_name - Delete members in "struct tomoyo_name". 312 * 302 * 313 * @element: Pointer to "struct list_head". 303 * @element: Pointer to "struct list_head". 314 * 304 * 315 * Returns nothing. 305 * Returns nothing. 316 */ 306 */ 317 static inline void tomoyo_del_name(struct list 307 static inline void tomoyo_del_name(struct list_head *element) 318 { 308 { 319 /* Nothing to do. */ 309 /* Nothing to do. */ 320 } 310 } 321 311 322 /** 312 /** 323 * tomoyo_del_path_group - Delete members in " 313 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group". 324 * 314 * 325 * @element: Pointer to "struct list_head". 315 * @element: Pointer to "struct list_head". 326 * 316 * 327 * Returns nothing. 317 * Returns nothing. 328 */ 318 */ 329 static inline void tomoyo_del_path_group(struc 319 static inline void tomoyo_del_path_group(struct list_head *element) 330 { 320 { 331 struct tomoyo_path_group *member = 321 struct tomoyo_path_group *member = 332 container_of(element, typeof(* 322 container_of(element, typeof(*member), head.list); 333 << 334 tomoyo_put_name(member->member_name); 323 tomoyo_put_name(member->member_name); 335 } 324 } 336 325 337 /** 326 /** 338 * tomoyo_del_group - Delete "struct tomoyo_gr 327 * tomoyo_del_group - Delete "struct tomoyo_group". 339 * 328 * 340 * @element: Pointer to "struct list_head". 329 * @element: Pointer to "struct list_head". 341 * 330 * 342 * Returns nothing. 331 * Returns nothing. 343 */ 332 */ 344 static inline void tomoyo_del_group(struct lis 333 static inline void tomoyo_del_group(struct list_head *element) 345 { 334 { 346 struct tomoyo_group *group = 335 struct tomoyo_group *group = 347 container_of(element, typeof(* 336 container_of(element, typeof(*group), head.list); 348 << 349 tomoyo_put_name(group->group_name); 337 tomoyo_put_name(group->group_name); 350 } 338 } 351 339 352 /** 340 /** 353 * tomoyo_del_address_group - Delete members i 341 * tomoyo_del_address_group - Delete members in "struct tomoyo_address_group". 354 * 342 * 355 * @element: Pointer to "struct list_head". 343 * @element: Pointer to "struct list_head". 356 * 344 * 357 * Returns nothing. 345 * Returns nothing. 358 */ 346 */ 359 static inline void tomoyo_del_address_group(st 347 static inline void tomoyo_del_address_group(struct list_head *element) 360 { 348 { 361 /* Nothing to do. */ 349 /* Nothing to do. */ 362 } 350 } 363 351 364 /** 352 /** 365 * tomoyo_del_number_group - Delete members in 353 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group". 366 * 354 * 367 * @element: Pointer to "struct list_head". 355 * @element: Pointer to "struct list_head". 368 * 356 * 369 * Returns nothing. 357 * Returns nothing. 370 */ 358 */ 371 static inline void tomoyo_del_number_group(str 359 static inline void tomoyo_del_number_group(struct list_head *element) 372 { 360 { 373 /* Nothing to do. */ 361 /* Nothing to do. */ 374 } 362 } 375 363 376 /** 364 /** 377 * tomoyo_try_to_gc - Try to kfree() an entry. 365 * tomoyo_try_to_gc - Try to kfree() an entry. 378 * 366 * 379 * @type: One of values in "enum tomoyo_pol 367 * @type: One of values in "enum tomoyo_policy_id". 380 * @element: Pointer to "struct list_head". 368 * @element: Pointer to "struct list_head". 381 * 369 * 382 * Returns nothing. 370 * Returns nothing. 383 * 371 * 384 * Caller holds tomoyo_policy_lock mutex. 372 * Caller holds tomoyo_policy_lock mutex. 385 */ 373 */ 386 static void tomoyo_try_to_gc(const enum tomoyo 374 static void tomoyo_try_to_gc(const enum tomoyo_policy_id type, 387 struct list_head 375 struct list_head *element) 388 { 376 { 389 /* 377 /* 390 * __list_del_entry() guarantees that 378 * __list_del_entry() guarantees that the list element became no longer 391 * reachable from the list which the e 379 * reachable from the list which the element was originally on (e.g. 392 * tomoyo_domain_list). Also, synchron 380 * tomoyo_domain_list). Also, synchronize_srcu() guarantees that the 393 * list element became no longer refer 381 * list element became no longer referenced by syscall users. 394 */ 382 */ 395 __list_del_entry(element); 383 __list_del_entry(element); 396 mutex_unlock(&tomoyo_policy_lock); 384 mutex_unlock(&tomoyo_policy_lock); 397 synchronize_srcu(&tomoyo_ss); 385 synchronize_srcu(&tomoyo_ss); 398 /* 386 /* 399 * However, there are two users which 387 * However, there are two users which may still be using the list 400 * element. We need to defer until bot 388 * element. We need to defer until both users forget this element. 401 * 389 * 402 * Don't kfree() until "struct tomoyo_ 390 * Don't kfree() until "struct tomoyo_io_buffer"->r.{domain,group,acl} 403 * and "struct tomoyo_io_buffer"->w.do 391 * and "struct tomoyo_io_buffer"->w.domain forget this element. 404 */ 392 */ 405 if (tomoyo_struct_used_by_io_buffer(el 393 if (tomoyo_struct_used_by_io_buffer(element)) 406 goto reinject; 394 goto reinject; 407 switch (type) { 395 switch (type) { 408 case TOMOYO_ID_TRANSITION_CONTROL: 396 case TOMOYO_ID_TRANSITION_CONTROL: 409 tomoyo_del_transition_control( 397 tomoyo_del_transition_control(element); 410 break; 398 break; 411 case TOMOYO_ID_MANAGER: 399 case TOMOYO_ID_MANAGER: 412 tomoyo_del_manager(element); 400 tomoyo_del_manager(element); 413 break; 401 break; 414 case TOMOYO_ID_AGGREGATOR: 402 case TOMOYO_ID_AGGREGATOR: 415 tomoyo_del_aggregator(element) 403 tomoyo_del_aggregator(element); 416 break; 404 break; 417 case TOMOYO_ID_GROUP: 405 case TOMOYO_ID_GROUP: 418 tomoyo_del_group(element); 406 tomoyo_del_group(element); 419 break; 407 break; 420 case TOMOYO_ID_PATH_GROUP: 408 case TOMOYO_ID_PATH_GROUP: 421 tomoyo_del_path_group(element) 409 tomoyo_del_path_group(element); 422 break; 410 break; 423 case TOMOYO_ID_ADDRESS_GROUP: 411 case TOMOYO_ID_ADDRESS_GROUP: 424 tomoyo_del_address_group(eleme 412 tomoyo_del_address_group(element); 425 break; 413 break; 426 case TOMOYO_ID_NUMBER_GROUP: 414 case TOMOYO_ID_NUMBER_GROUP: 427 tomoyo_del_number_group(elemen 415 tomoyo_del_number_group(element); 428 break; 416 break; 429 case TOMOYO_ID_CONDITION: 417 case TOMOYO_ID_CONDITION: 430 tomoyo_del_condition(element); 418 tomoyo_del_condition(element); 431 break; 419 break; 432 case TOMOYO_ID_NAME: 420 case TOMOYO_ID_NAME: 433 /* 421 /* 434 * Don't kfree() until all "st 422 * Don't kfree() until all "struct tomoyo_io_buffer"->r.w[] 435 * forget this element. 423 * forget this element. 436 */ 424 */ 437 if (tomoyo_name_used_by_io_buf 425 if (tomoyo_name_used_by_io_buffer 438 (container_of(element, typ 426 (container_of(element, typeof(struct tomoyo_name), 439 head.list)-> 427 head.list)->entry.name)) 440 goto reinject; 428 goto reinject; 441 tomoyo_del_name(element); 429 tomoyo_del_name(element); 442 break; 430 break; 443 case TOMOYO_ID_ACL: 431 case TOMOYO_ID_ACL: 444 tomoyo_del_acl(element); 432 tomoyo_del_acl(element); 445 break; 433 break; 446 case TOMOYO_ID_DOMAIN: 434 case TOMOYO_ID_DOMAIN: 447 /* 435 /* 448 * Don't kfree() until all "st 436 * Don't kfree() until all "struct cred"->security forget this 449 * element. 437 * element. 450 */ 438 */ 451 if (atomic_read(&container_of 439 if (atomic_read(&container_of 452 (element, type 440 (element, typeof(struct tomoyo_domain_info), 453 list)->users) 441 list)->users)) 454 goto reinject; 442 goto reinject; 455 break; 443 break; 456 case TOMOYO_MAX_POLICY: 444 case TOMOYO_MAX_POLICY: 457 break; 445 break; 458 } 446 } 459 mutex_lock(&tomoyo_policy_lock); 447 mutex_lock(&tomoyo_policy_lock); 460 if (type == TOMOYO_ID_DOMAIN) 448 if (type == TOMOYO_ID_DOMAIN) 461 tomoyo_del_domain(element); 449 tomoyo_del_domain(element); 462 tomoyo_memory_free(element); 450 tomoyo_memory_free(element); 463 return; 451 return; 464 reinject: 452 reinject: 465 /* 453 /* 466 * We can safely reinject this element !! 454 * We can safely reinject this element here bacause 467 * (1) Appending list elements and rem 455 * (1) Appending list elements and removing list elements are protected 468 * by tomoyo_policy_lock mutex. 456 * by tomoyo_policy_lock mutex. 469 * (2) Only this function removes list 457 * (2) Only this function removes list elements and this function is 470 * exclusively executed by tomoyo_ 458 * exclusively executed by tomoyo_gc_mutex mutex. 471 * are true. 459 * are true. 472 */ 460 */ 473 mutex_lock(&tomoyo_policy_lock); 461 mutex_lock(&tomoyo_policy_lock); 474 list_add_rcu(element, element->prev); 462 list_add_rcu(element, element->prev); 475 } 463 } 476 464 477 /** 465 /** 478 * tomoyo_collect_member - Delete elements wit 466 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head". 479 * 467 * 480 * @id: One of values in "enum tomoyo 468 * @id: One of values in "enum tomoyo_policy_id". 481 * @member_list: Pointer to "struct list_head" 469 * @member_list: Pointer to "struct list_head". 482 * 470 * 483 * Returns nothing. 471 * Returns nothing. 484 */ 472 */ 485 static void tomoyo_collect_member(const enum t 473 static void tomoyo_collect_member(const enum tomoyo_policy_id id, 486 struct list_ 474 struct list_head *member_list) 487 { 475 { 488 struct tomoyo_acl_head *member; 476 struct tomoyo_acl_head *member; 489 struct tomoyo_acl_head *tmp; 477 struct tomoyo_acl_head *tmp; 490 << 491 list_for_each_entry_safe(member, tmp, 478 list_for_each_entry_safe(member, tmp, member_list, list) { 492 if (!member->is_deleted) 479 if (!member->is_deleted) 493 continue; 480 continue; 494 member->is_deleted = TOMOYO_GC 481 member->is_deleted = TOMOYO_GC_IN_PROGRESS; 495 tomoyo_try_to_gc(id, &member-> 482 tomoyo_try_to_gc(id, &member->list); 496 } 483 } 497 } 484 } 498 485 499 /** 486 /** 500 * tomoyo_collect_acl - Delete elements in "st 487 * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info". 501 * 488 * 502 * @list: Pointer to "struct list_head". 489 * @list: Pointer to "struct list_head". 503 * 490 * 504 * Returns nothing. 491 * Returns nothing. 505 */ 492 */ 506 static void tomoyo_collect_acl(struct list_hea 493 static void tomoyo_collect_acl(struct list_head *list) 507 { 494 { 508 struct tomoyo_acl_info *acl; 495 struct tomoyo_acl_info *acl; 509 struct tomoyo_acl_info *tmp; 496 struct tomoyo_acl_info *tmp; 510 << 511 list_for_each_entry_safe(acl, tmp, lis 497 list_for_each_entry_safe(acl, tmp, list, list) { 512 if (!acl->is_deleted) 498 if (!acl->is_deleted) 513 continue; 499 continue; 514 acl->is_deleted = TOMOYO_GC_IN 500 acl->is_deleted = TOMOYO_GC_IN_PROGRESS; 515 tomoyo_try_to_gc(TOMOYO_ID_ACL 501 tomoyo_try_to_gc(TOMOYO_ID_ACL, &acl->list); 516 } 502 } 517 } 503 } 518 504 519 /** 505 /** 520 * tomoyo_collect_entry - Try to kfree() delet 506 * tomoyo_collect_entry - Try to kfree() deleted elements. 521 * 507 * 522 * Returns nothing. 508 * Returns nothing. 523 */ 509 */ 524 static void tomoyo_collect_entry(void) 510 static void tomoyo_collect_entry(void) 525 { 511 { 526 int i; 512 int i; 527 enum tomoyo_policy_id id; 513 enum tomoyo_policy_id id; 528 struct tomoyo_policy_namespace *ns; 514 struct tomoyo_policy_namespace *ns; 529 << 530 mutex_lock(&tomoyo_policy_lock); 515 mutex_lock(&tomoyo_policy_lock); 531 { 516 { 532 struct tomoyo_domain_info *dom 517 struct tomoyo_domain_info *domain; 533 struct tomoyo_domain_info *tmp 518 struct tomoyo_domain_info *tmp; 534 << 535 list_for_each_entry_safe(domai 519 list_for_each_entry_safe(domain, tmp, &tomoyo_domain_list, 536 list) 520 list) { 537 tomoyo_collect_acl(&do 521 tomoyo_collect_acl(&domain->acl_info_list); 538 if (!domain->is_delete 522 if (!domain->is_deleted || atomic_read(&domain->users)) 539 continue; 523 continue; 540 tomoyo_try_to_gc(TOMOY 524 tomoyo_try_to_gc(TOMOYO_ID_DOMAIN, &domain->list); 541 } 525 } 542 } 526 } 543 list_for_each_entry(ns, &tomoyo_namesp 527 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) { 544 for (id = 0; id < TOMOYO_MAX_P 528 for (id = 0; id < TOMOYO_MAX_POLICY; id++) 545 tomoyo_collect_member( 529 tomoyo_collect_member(id, &ns->policy_list[id]); 546 for (i = 0; i < TOMOYO_MAX_ACL 530 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++) 547 tomoyo_collect_acl(&ns 531 tomoyo_collect_acl(&ns->acl_group[i]); 548 } 532 } 549 { 533 { 550 struct tomoyo_shared_acl_head 534 struct tomoyo_shared_acl_head *ptr; 551 struct tomoyo_shared_acl_head 535 struct tomoyo_shared_acl_head *tmp; 552 << 553 list_for_each_entry_safe(ptr, 536 list_for_each_entry_safe(ptr, tmp, &tomoyo_condition_list, 554 list) 537 list) { 555 if (atomic_read(&ptr-> 538 if (atomic_read(&ptr->users) > 0) 556 continue; 539 continue; 557 atomic_set(&ptr->users 540 atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS); 558 tomoyo_try_to_gc(TOMOY 541 tomoyo_try_to_gc(TOMOYO_ID_CONDITION, &ptr->list); 559 } 542 } 560 } 543 } 561 list_for_each_entry(ns, &tomoyo_namesp 544 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) { 562 for (i = 0; i < TOMOYO_MAX_GRO 545 for (i = 0; i < TOMOYO_MAX_GROUP; i++) { 563 struct list_head *list 546 struct list_head *list = &ns->group_list[i]; 564 struct tomoyo_group *g 547 struct tomoyo_group *group; 565 struct tomoyo_group *t 548 struct tomoyo_group *tmp; 566 << 567 switch (i) { 549 switch (i) { 568 case 0: 550 case 0: 569 id = TOMOYO_ID 551 id = TOMOYO_ID_PATH_GROUP; 570 break; 552 break; 571 case 1: 553 case 1: 572 id = TOMOYO_ID 554 id = TOMOYO_ID_NUMBER_GROUP; 573 break; 555 break; 574 default: 556 default: 575 id = TOMOYO_ID 557 id = TOMOYO_ID_ADDRESS_GROUP; 576 break; 558 break; 577 } 559 } 578 list_for_each_entry_sa 560 list_for_each_entry_safe(group, tmp, list, head.list) { 579 tomoyo_collect 561 tomoyo_collect_member(id, &group->member_list); 580 if (!list_empt 562 if (!list_empty(&group->member_list) || 581 atomic_rea 563 atomic_read(&group->head.users) > 0) 582 contin 564 continue; 583 atomic_set(&gr 565 atomic_set(&group->head.users, 584 TOM 566 TOMOYO_GC_IN_PROGRESS); 585 tomoyo_try_to_ 567 tomoyo_try_to_gc(TOMOYO_ID_GROUP, 586 568 &group->head.list); 587 } 569 } 588 } 570 } 589 } 571 } 590 for (i = 0; i < TOMOYO_MAX_HASH; i++) 572 for (i = 0; i < TOMOYO_MAX_HASH; i++) { 591 struct list_head *list = &tomo 573 struct list_head *list = &tomoyo_name_list[i]; 592 struct tomoyo_shared_acl_head 574 struct tomoyo_shared_acl_head *ptr; 593 struct tomoyo_shared_acl_head 575 struct tomoyo_shared_acl_head *tmp; 594 << 595 list_for_each_entry_safe(ptr, 576 list_for_each_entry_safe(ptr, tmp, list, list) { 596 if (atomic_read(&ptr-> 577 if (atomic_read(&ptr->users) > 0) 597 continue; 578 continue; 598 atomic_set(&ptr->users 579 atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS); 599 tomoyo_try_to_gc(TOMOY 580 tomoyo_try_to_gc(TOMOYO_ID_NAME, &ptr->list); 600 } 581 } 601 } 582 } 602 mutex_unlock(&tomoyo_policy_lock); 583 mutex_unlock(&tomoyo_policy_lock); 603 } 584 } 604 585 605 /** 586 /** 606 * tomoyo_gc_thread - Garbage collector thread 587 * tomoyo_gc_thread - Garbage collector thread function. 607 * 588 * 608 * @unused: Unused. 589 * @unused: Unused. 609 * 590 * 610 * Returns 0. 591 * Returns 0. 611 */ 592 */ 612 static int tomoyo_gc_thread(void *unused) 593 static int tomoyo_gc_thread(void *unused) 613 { 594 { 614 /* Garbage collector thread is exclusi 595 /* Garbage collector thread is exclusive. */ 615 static DEFINE_MUTEX(tomoyo_gc_mutex); 596 static DEFINE_MUTEX(tomoyo_gc_mutex); 616 << 617 if (!mutex_trylock(&tomoyo_gc_mutex)) 597 if (!mutex_trylock(&tomoyo_gc_mutex)) 618 goto out; 598 goto out; 619 tomoyo_collect_entry(); 599 tomoyo_collect_entry(); 620 { 600 { 621 struct tomoyo_io_buffer *head; 601 struct tomoyo_io_buffer *head; 622 struct tomoyo_io_buffer *tmp; 602 struct tomoyo_io_buffer *tmp; 623 603 624 spin_lock(&tomoyo_io_buffer_li 604 spin_lock(&tomoyo_io_buffer_list_lock); 625 list_for_each_entry_safe(head, 605 list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list, 626 list) 606 list) { 627 if (head->users) 607 if (head->users) 628 continue; 608 continue; 629 list_del(&head->list); 609 list_del(&head->list); 630 kfree(head->read_buf); 610 kfree(head->read_buf); 631 kfree(head->write_buf) 611 kfree(head->write_buf); 632 kfree(head); 612 kfree(head); 633 } 613 } 634 spin_unlock(&tomoyo_io_buffer_ 614 spin_unlock(&tomoyo_io_buffer_list_lock); 635 } 615 } 636 mutex_unlock(&tomoyo_gc_mutex); 616 mutex_unlock(&tomoyo_gc_mutex); 637 out: 617 out: 638 /* This acts as do_exit(0). */ 618 /* This acts as do_exit(0). */ 639 return 0; 619 return 0; 640 } 620 } 641 621 642 /** 622 /** 643 * tomoyo_notify_gc - Register/unregister /sys 623 * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users. 644 * 624 * 645 * @head: Pointer to "struct tomoyo_io_ 625 * @head: Pointer to "struct tomoyo_io_buffer". 646 * @is_register: True if register, false if un 626 * @is_register: True if register, false if unregister. 647 * 627 * 648 * Returns nothing. 628 * Returns nothing. 649 */ 629 */ 650 void tomoyo_notify_gc(struct tomoyo_io_buffer 630 void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register) 651 { 631 { 652 bool is_write = false; 632 bool is_write = false; 653 633 654 spin_lock(&tomoyo_io_buffer_list_lock) 634 spin_lock(&tomoyo_io_buffer_list_lock); 655 if (is_register) { 635 if (is_register) { 656 head->users = 1; 636 head->users = 1; 657 list_add(&head->list, &tomoyo_ 637 list_add(&head->list, &tomoyo_io_buffer_list); 658 } else { 638 } else { 659 is_write = head->write_buf != 639 is_write = head->write_buf != NULL; 660 if (!--head->users) { 640 if (!--head->users) { 661 list_del(&head->list); 641 list_del(&head->list); 662 kfree(head->read_buf); 642 kfree(head->read_buf); 663 kfree(head->write_buf) 643 kfree(head->write_buf); 664 kfree(head); 644 kfree(head); 665 } 645 } 666 } 646 } 667 spin_unlock(&tomoyo_io_buffer_list_loc 647 spin_unlock(&tomoyo_io_buffer_list_lock); 668 if (is_write) !! 648 if (is_write) { 669 kthread_run(tomoyo_gc_thread, !! 649 struct task_struct *task = kthread_create(tomoyo_gc_thread, >> 650 NULL, >> 651 "GC for TOMOYO"); >> 652 if (!IS_ERR(task)) >> 653 wake_up_process(task); >> 654 } 670 } 655 } 671 656
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.