1 /* 2 * security/tomoyo/gc.c 3 * 4 * Implementation of the Domain-Based Mandatory Access Control. 5 * 6 * Copyright (C) 2005-2010 NTT DATA CORPORATION 7 * 8 */ 9 10 #include "common.h" 11 #include <linux/kthread.h> 12 #include <linux/slab.h> 13 14 struct tomoyo_gc { 15 struct list_head list; 16 int type; 17 struct list_head *element; 18 }; 19 static LIST_HEAD(tomoyo_gc_queue); 20 static DEFINE_MUTEX(tomoyo_gc_mutex); 21 22 /* Caller holds tomoyo_policy_lock mutex. */ 23 static bool tomoyo_add_to_gc(const int type, struct list_head *element) 24 { 25 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 26 if (!entry) 27 return false; 28 entry->type = type; 29 entry->element = element; 30 list_add(&entry->list, &tomoyo_gc_queue); 31 list_del_rcu(element); 32 return true; 33 } 34 35 static void tomoyo_del_allow_read(struct list_head *element) 36 { 37 struct tomoyo_readable_file *ptr = 38 container_of(element, typeof(*ptr), head.list); 39 tomoyo_put_name(ptr->filename); 40 } 41 42 static void tomoyo_del_file_pattern(struct list_head *element) 43 { 44 struct tomoyo_no_pattern *ptr = 45 container_of(element, typeof(*ptr), head.list); 46 tomoyo_put_name(ptr->pattern); 47 } 48 49 static void tomoyo_del_no_rewrite(struct list_head *element) 50 { 51 struct tomoyo_no_rewrite *ptr = 52 container_of(element, typeof(*ptr), head.list); 53 tomoyo_put_name(ptr->pattern); 54 } 55 56 static void tomoyo_del_transition_control(struct list_head *element) 57 { 58 struct tomoyo_transition_control *ptr = 59 container_of(element, typeof(*ptr), head.list); 60 tomoyo_put_name(ptr->domainname); 61 tomoyo_put_name(ptr->program); 62 } 63 64 static void tomoyo_del_aggregator(struct list_head *element) 65 { 66 struct tomoyo_aggregator *ptr = 67 container_of(element, typeof(*ptr), head.list); 68 tomoyo_put_name(ptr->original_name); 69 tomoyo_put_name(ptr->aggregated_name); 70 } 71 72 static void tomoyo_del_manager(struct list_head *element) 73 { 74 struct tomoyo_manager *ptr = 75 container_of(element, typeof(*ptr), head.list); 76 tomoyo_put_name(ptr->manager); 77 } 78 79 static void tomoyo_del_acl(struct list_head *element) 80 { 81 struct tomoyo_acl_info *acl = 82 container_of(element, typeof(*acl), list); 83 switch (acl->type) { 84 case TOMOYO_TYPE_PATH_ACL: 85 { 86 struct tomoyo_path_acl *entry 87 = container_of(acl, typeof(*entry), head); 88 tomoyo_put_name_union(&entry->name); 89 } 90 break; 91 case TOMOYO_TYPE_PATH2_ACL: 92 { 93 struct tomoyo_path2_acl *entry 94 = container_of(acl, typeof(*entry), head); 95 tomoyo_put_name_union(&entry->name1); 96 tomoyo_put_name_union(&entry->name2); 97 } 98 break; 99 case TOMOYO_TYPE_PATH_NUMBER_ACL: 100 { 101 struct tomoyo_path_number_acl *entry 102 = container_of(acl, typeof(*entry), head); 103 tomoyo_put_name_union(&entry->name); 104 tomoyo_put_number_union(&entry->number); 105 } 106 break; 107 case TOMOYO_TYPE_MKDEV_ACL: 108 { 109 struct tomoyo_mkdev_acl *entry 110 = container_of(acl, typeof(*entry), head); 111 tomoyo_put_name_union(&entry->name); 112 tomoyo_put_number_union(&entry->mode); 113 tomoyo_put_number_union(&entry->major); 114 tomoyo_put_number_union(&entry->minor); 115 } 116 break; 117 case TOMOYO_TYPE_MOUNT_ACL: 118 { 119 struct tomoyo_mount_acl *entry 120 = container_of(acl, typeof(*entry), head); 121 tomoyo_put_name_union(&entry->dev_name); 122 tomoyo_put_name_union(&entry->dir_name); 123 tomoyo_put_name_union(&entry->fs_type); 124 tomoyo_put_number_union(&entry->flags); 125 } 126 break; 127 } 128 } 129 130 static bool tomoyo_del_domain(struct list_head *element) 131 { 132 struct tomoyo_domain_info *domain = 133 container_of(element, typeof(*domain), list); 134 struct tomoyo_acl_info *acl; 135 struct tomoyo_acl_info *tmp; 136 /* 137 * Since we don't protect whole execve() operation using SRCU, 138 * we need to recheck domain->users at this point. 139 * 140 * (1) Reader starts SRCU section upon execve(). 141 * (2) Reader traverses tomoyo_domain_list and finds this domain. 142 * (3) Writer marks this domain as deleted. 143 * (4) Garbage collector removes this domain from tomoyo_domain_list 144 * because this domain is marked as deleted and used by nobody. 145 * (5) Reader saves reference to this domain into 146 * "struct linux_binprm"->cred->security . 147 * (6) Reader finishes SRCU section, although execve() operation has 148 * not finished yet. 149 * (7) Garbage collector waits for SRCU synchronization. 150 * (8) Garbage collector kfree() this domain because this domain is 151 * used by nobody. 152 * (9) Reader finishes execve() operation and restores this domain from 153 * "struct linux_binprm"->cred->security. 154 * 155 * By updating domain->users at (5), we can solve this race problem 156 * by rechecking domain->users at (8). 157 */ 158 if (atomic_read(&domain->users)) 159 return false; 160 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) { 161 tomoyo_del_acl(&acl->list); 162 tomoyo_memory_free(acl); 163 } 164 tomoyo_put_name(domain->domainname); 165 return true; 166 } 167 168 169 static void tomoyo_del_name(struct list_head *element) 170 { 171 const struct tomoyo_name *ptr = 172 container_of(element, typeof(*ptr), list); 173 } 174 175 static void tomoyo_del_path_group(struct list_head *element) 176 { 177 struct tomoyo_path_group *member = 178 container_of(element, typeof(*member), head.list); 179 tomoyo_put_name(member->member_name); 180 } 181 182 static void tomoyo_del_group(struct list_head *element) 183 { 184 struct tomoyo_group *group = 185 container_of(element, typeof(*group), list); 186 tomoyo_put_name(group->group_name); 187 } 188 189 static void tomoyo_del_number_group(struct list_head *element) 190 { 191 struct tomoyo_number_group *member = 192 container_of(element, typeof(*member), head.list); 193 } 194 195 static bool tomoyo_collect_member(struct list_head *member_list, int id) 196 { 197 struct tomoyo_acl_head *member; 198 list_for_each_entry(member, member_list, list) { 199 if (!member->is_deleted) 200 continue; 201 if (!tomoyo_add_to_gc(id, &member->list)) 202 return false; 203 } 204 return true; 205 } 206 207 static bool tomoyo_collect_acl(struct tomoyo_domain_info *domain) 208 { 209 struct tomoyo_acl_info *acl; 210 list_for_each_entry(acl, &domain->acl_info_list, list) { 211 if (!acl->is_deleted) 212 continue; 213 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list)) 214 return false; 215 } 216 return true; 217 } 218 219 static void tomoyo_collect_entry(void) 220 { 221 int i; 222 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 223 return; 224 for (i = 0; i < TOMOYO_MAX_POLICY; i++) { 225 if (!tomoyo_collect_member(&tomoyo_policy_list[i], i)) 226 goto unlock; 227 } 228 { 229 struct tomoyo_domain_info *domain; 230 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 231 if (!tomoyo_collect_acl(domain)) 232 goto unlock; 233 if (!domain->is_deleted || atomic_read(&domain->users)) 234 continue; 235 /* 236 * Nobody is referring this domain. But somebody may 237 * refer this domain after successful execve(). 238 * We recheck domain->users after SRCU synchronization. 239 */ 240 if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list)) 241 goto unlock; 242 } 243 } 244 for (i = 0; i < TOMOYO_MAX_HASH; i++) { 245 struct tomoyo_name *ptr; 246 list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], list) { 247 if (atomic_read(&ptr->users)) 248 continue; 249 if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->list)) 250 goto unlock; 251 } 252 } 253 for (i = 0; i < TOMOYO_MAX_GROUP; i++) { 254 struct list_head *list = &tomoyo_group_list[i]; 255 int id; 256 struct tomoyo_group *group; 257 switch (i) { 258 case 0: 259 id = TOMOYO_ID_PATH_GROUP; 260 break; 261 default: 262 id = TOMOYO_ID_NUMBER_GROUP; 263 break; 264 } 265 list_for_each_entry(group, list, list) { 266 if (!tomoyo_collect_member(&group->member_list, id)) 267 goto unlock; 268 if (!list_empty(&group->member_list) || 269 atomic_read(&group->users)) 270 continue; 271 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP, &group->list)) 272 goto unlock; 273 } 274 } 275 unlock: 276 mutex_unlock(&tomoyo_policy_lock); 277 } 278 279 static void tomoyo_kfree_entry(void) 280 { 281 struct tomoyo_gc *p; 282 struct tomoyo_gc *tmp; 283 284 list_for_each_entry_safe(p, tmp, &tomoyo_gc_queue, list) { 285 struct list_head *element = p->element; 286 switch (p->type) { 287 case TOMOYO_ID_TRANSITION_CONTROL: 288 tomoyo_del_transition_control(element); 289 break; 290 case TOMOYO_ID_AGGREGATOR: 291 tomoyo_del_aggregator(element); 292 break; 293 case TOMOYO_ID_GLOBALLY_READABLE: 294 tomoyo_del_allow_read(element); 295 break; 296 case TOMOYO_ID_PATTERN: 297 tomoyo_del_file_pattern(element); 298 break; 299 case TOMOYO_ID_NO_REWRITE: 300 tomoyo_del_no_rewrite(element); 301 break; 302 case TOMOYO_ID_MANAGER: 303 tomoyo_del_manager(element); 304 break; 305 case TOMOYO_ID_NAME: 306 tomoyo_del_name(element); 307 break; 308 case TOMOYO_ID_ACL: 309 tomoyo_del_acl(element); 310 break; 311 case TOMOYO_ID_DOMAIN: 312 if (!tomoyo_del_domain(element)) 313 continue; 314 break; 315 case TOMOYO_ID_PATH_GROUP: 316 tomoyo_del_path_group(element); 317 break; 318 case TOMOYO_ID_GROUP: 319 tomoyo_del_group(element); 320 break; 321 case TOMOYO_ID_NUMBER_GROUP: 322 tomoyo_del_number_group(element); 323 break; 324 } 325 tomoyo_memory_free(element); 326 list_del(&p->list); 327 kfree(p); 328 } 329 } 330 331 static int tomoyo_gc_thread(void *unused) 332 { 333 daemonize("GC for TOMOYO"); 334 if (mutex_trylock(&tomoyo_gc_mutex)) { 335 int i; 336 for (i = 0; i < 10; i++) { 337 tomoyo_collect_entry(); 338 if (list_empty(&tomoyo_gc_queue)) 339 break; 340 synchronize_srcu(&tomoyo_ss); 341 tomoyo_kfree_entry(); 342 } 343 mutex_unlock(&tomoyo_gc_mutex); 344 } 345 do_exit(0); 346 } 347 348 void tomoyo_run_gc(void) 349 { 350 struct task_struct *task = kthread_create(tomoyo_gc_thread, NULL, 351 "GC for TOMOYO"); 352 if (!IS_ERR(task)) 353 wake_up_process(task); 354 } 355