aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/domain.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/domain.c')
-rw-r--r--security/tomoyo/domain.c124
1 files changed, 48 insertions, 76 deletions
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index a1723bbcde0..cd8ba444676 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -130,58 +130,47 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
130 const bool is_not, 130 const bool is_not,
131 const bool is_delete) 131 const bool is_delete)
132{ 132{
133 struct tomoyo_domain_initializer_entry *entry = NULL;
134 struct tomoyo_domain_initializer_entry *ptr; 133 struct tomoyo_domain_initializer_entry *ptr;
135 const struct tomoyo_path_info *saved_program = NULL; 134 struct tomoyo_domain_initializer_entry e = { .is_not = is_not };
136 const struct tomoyo_path_info *saved_domainname = NULL;
137 int error = is_delete ? -ENOENT : -ENOMEM; 135 int error = is_delete ? -ENOENT : -ENOMEM;
138 bool is_last_name = false;
139 136
140 if (!tomoyo_is_correct_path(program, 1, -1, -1)) 137 if (!tomoyo_is_correct_path(program, 1, -1, -1))
141 return -EINVAL; /* No patterns allowed. */ 138 return -EINVAL; /* No patterns allowed. */
142 if (domainname) { 139 if (domainname) {
143 if (!tomoyo_is_domain_def(domainname) && 140 if (!tomoyo_is_domain_def(domainname) &&
144 tomoyo_is_correct_path(domainname, 1, -1, -1)) 141 tomoyo_is_correct_path(domainname, 1, -1, -1))
145 is_last_name = true; 142 e.is_last_name = true;
146 else if (!tomoyo_is_correct_domain(domainname)) 143 else if (!tomoyo_is_correct_domain(domainname))
147 return -EINVAL; 144 return -EINVAL;
148 saved_domainname = tomoyo_get_name(domainname); 145 e.domainname = tomoyo_get_name(domainname);
149 if (!saved_domainname) 146 if (!e.domainname)
150 goto out; 147 goto out;
151 } 148 }
152 saved_program = tomoyo_get_name(program); 149 e.program = tomoyo_get_name(program);
153 if (!saved_program) 150 if (!e.program)
154 goto out; 151 goto out;
155 if (!is_delete)
156 entry = kmalloc(sizeof(*entry), GFP_NOFS);
157 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 152 if (mutex_lock_interruptible(&tomoyo_policy_lock))
158 goto out; 153 goto out;
159 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) { 154 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
160 if (ptr->is_not != is_not || 155 if (!tomoyo_is_same_domain_initializer_entry(ptr, &e))
161 ptr->domainname != saved_domainname ||
162 ptr->program != saved_program)
163 continue; 156 continue;
164 ptr->is_deleted = is_delete; 157 ptr->is_deleted = is_delete;
165 error = 0; 158 error = 0;
166 break; 159 break;
167 } 160 }
168 if (!is_delete && error && tomoyo_memory_ok(entry)) { 161 if (!is_delete && error) {
169 entry->domainname = saved_domainname; 162 struct tomoyo_domain_initializer_entry *entry =
170 saved_domainname = NULL; 163 tomoyo_commit_ok(&e, sizeof(e));
171 entry->program = saved_program; 164 if (entry) {
172 saved_program = NULL; 165 list_add_tail_rcu(&entry->list,
173 entry->is_not = is_not; 166 &tomoyo_domain_initializer_list);
174 entry->is_last_name = is_last_name; 167 error = 0;
175 list_add_tail_rcu(&entry->list, 168 }
176 &tomoyo_domain_initializer_list);
177 entry = NULL;
178 error = 0;
179 } 169 }
180 mutex_unlock(&tomoyo_policy_lock); 170 mutex_unlock(&tomoyo_policy_lock);
181 out: 171 out:
182 tomoyo_put_name(saved_domainname); 172 tomoyo_put_name(e.domainname);
183 tomoyo_put_name(saved_program); 173 tomoyo_put_name(e.program);
184 kfree(entry);
185 return error; 174 return error;
186} 175}
187 176
@@ -351,57 +340,47 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
351 const bool is_not, 340 const bool is_not,
352 const bool is_delete) 341 const bool is_delete)
353{ 342{
354 struct tomoyo_domain_keeper_entry *entry = NULL;
355 struct tomoyo_domain_keeper_entry *ptr; 343 struct tomoyo_domain_keeper_entry *ptr;
356 const struct tomoyo_path_info *saved_domainname = NULL; 344 struct tomoyo_domain_keeper_entry e = { .is_not = is_not };
357 const struct tomoyo_path_info *saved_program = NULL;
358 int error = is_delete ? -ENOENT : -ENOMEM; 345 int error = is_delete ? -ENOENT : -ENOMEM;
359 bool is_last_name = false;
360 346
361 if (!tomoyo_is_domain_def(domainname) && 347 if (!tomoyo_is_domain_def(domainname) &&
362 tomoyo_is_correct_path(domainname, 1, -1, -1)) 348 tomoyo_is_correct_path(domainname, 1, -1, -1))
363 is_last_name = true; 349 e.is_last_name = true;
364 else if (!tomoyo_is_correct_domain(domainname)) 350 else if (!tomoyo_is_correct_domain(domainname))
365 return -EINVAL; 351 return -EINVAL;
366 if (program) { 352 if (program) {
367 if (!tomoyo_is_correct_path(program, 1, -1, -1)) 353 if (!tomoyo_is_correct_path(program, 1, -1, -1))
368 return -EINVAL; 354 return -EINVAL;
369 saved_program = tomoyo_get_name(program); 355 e.program = tomoyo_get_name(program);
370 if (!saved_program) 356 if (!e.program)
371 goto out; 357 goto out;
372 } 358 }
373 saved_domainname = tomoyo_get_name(domainname); 359 e.domainname = tomoyo_get_name(domainname);
374 if (!saved_domainname) 360 if (!e.domainname)
375 goto out; 361 goto out;
376 if (!is_delete)
377 entry = kmalloc(sizeof(*entry), GFP_NOFS);
378 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 362 if (mutex_lock_interruptible(&tomoyo_policy_lock))
379 goto out; 363 goto out;
380 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) { 364 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
381 if (ptr->is_not != is_not || 365 if (!tomoyo_is_same_domain_keeper_entry(ptr, &e))
382 ptr->domainname != saved_domainname ||
383 ptr->program != saved_program)
384 continue; 366 continue;
385 ptr->is_deleted = is_delete; 367 ptr->is_deleted = is_delete;
386 error = 0; 368 error = 0;
387 break; 369 break;
388 } 370 }
389 if (!is_delete && error && tomoyo_memory_ok(entry)) { 371 if (!is_delete && error) {
390 entry->domainname = saved_domainname; 372 struct tomoyo_domain_keeper_entry *entry =
391 saved_domainname = NULL; 373 tomoyo_commit_ok(&e, sizeof(e));
392 entry->program = saved_program; 374 if (entry) {
393 saved_program = NULL; 375 list_add_tail_rcu(&entry->list,
394 entry->is_not = is_not; 376 &tomoyo_domain_keeper_list);
395 entry->is_last_name = is_last_name; 377 error = 0;
396 list_add_tail_rcu(&entry->list, &tomoyo_domain_keeper_list); 378 }
397 entry = NULL;
398 error = 0;
399 } 379 }
400 mutex_unlock(&tomoyo_policy_lock); 380 mutex_unlock(&tomoyo_policy_lock);
401 out: 381 out:
402 tomoyo_put_name(saved_domainname); 382 tomoyo_put_name(e.domainname);
403 tomoyo_put_name(saved_program); 383 tomoyo_put_name(e.program);
404 kfree(entry);
405 return error; 384 return error;
406} 385}
407 386
@@ -553,45 +532,38 @@ static int tomoyo_update_alias_entry(const char *original_name,
553 const char *aliased_name, 532 const char *aliased_name,
554 const bool is_delete) 533 const bool is_delete)
555{ 534{
556 struct tomoyo_alias_entry *entry = NULL;
557 struct tomoyo_alias_entry *ptr; 535 struct tomoyo_alias_entry *ptr;
558 const struct tomoyo_path_info *saved_original_name; 536 struct tomoyo_alias_entry e = { };
559 const struct tomoyo_path_info *saved_aliased_name;
560 int error = is_delete ? -ENOENT : -ENOMEM; 537 int error = is_delete ? -ENOENT : -ENOMEM;
561 538
562 if (!tomoyo_is_correct_path(original_name, 1, -1, -1) || 539 if (!tomoyo_is_correct_path(original_name, 1, -1, -1) ||
563 !tomoyo_is_correct_path(aliased_name, 1, -1, -1)) 540 !tomoyo_is_correct_path(aliased_name, 1, -1, -1))
564 return -EINVAL; /* No patterns allowed. */ 541 return -EINVAL; /* No patterns allowed. */
565 saved_original_name = tomoyo_get_name(original_name); 542 e.original_name = tomoyo_get_name(original_name);
566 saved_aliased_name = tomoyo_get_name(aliased_name); 543 e.aliased_name = tomoyo_get_name(aliased_name);
567 if (!saved_original_name || !saved_aliased_name) 544 if (!e.original_name || !e.aliased_name)
568 goto out; 545 goto out;
569 if (!is_delete)
570 entry = kmalloc(sizeof(*entry), GFP_NOFS);
571 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 546 if (mutex_lock_interruptible(&tomoyo_policy_lock))
572 goto out; 547 goto out;
573 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) { 548 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
574 if (ptr->original_name != saved_original_name || 549 if (!tomoyo_is_same_alias_entry(ptr, &e))
575 ptr->aliased_name != saved_aliased_name)
576 continue; 550 continue;
577 ptr->is_deleted = is_delete; 551 ptr->is_deleted = is_delete;
578 error = 0; 552 error = 0;
579 break; 553 break;
580 } 554 }
581 if (!is_delete && error && tomoyo_memory_ok(entry)) { 555 if (!is_delete && error) {
582 entry->original_name = saved_original_name; 556 struct tomoyo_alias_entry *entry =
583 saved_original_name = NULL; 557 tomoyo_commit_ok(&e, sizeof(e));
584 entry->aliased_name = saved_aliased_name; 558 if (entry) {
585 saved_aliased_name = NULL; 559 list_add_tail_rcu(&entry->list, &tomoyo_alias_list);
586 list_add_tail_rcu(&entry->list, &tomoyo_alias_list); 560 error = 0;
587 entry = NULL; 561 }
588 error = 0;
589 } 562 }
590 mutex_unlock(&tomoyo_policy_lock); 563 mutex_unlock(&tomoyo_policy_lock);
591 out: 564 out:
592 tomoyo_put_name(saved_original_name); 565 tomoyo_put_name(e.original_name);
593 tomoyo_put_name(saved_aliased_name); 566 tomoyo_put_name(e.aliased_name);
594 kfree(entry);
595 return error; 567 return error;
596} 568}
597 569