aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/tomoyo/common.c28
-rw-r--r--security/tomoyo/domain.c147
-rw-r--r--security/tomoyo/file.c234
3 files changed, 183 insertions, 226 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index ae3ed7313ee0..a53ee059da48 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1103,10 +1103,10 @@ static LIST_HEAD(tomoyo_policy_manager_list);
1103static int tomoyo_update_manager_entry(const char *manager, 1103static int tomoyo_update_manager_entry(const char *manager,
1104 const bool is_delete) 1104 const bool is_delete)
1105{ 1105{
1106 struct tomoyo_policy_manager_entry *new_entry; 1106 struct tomoyo_policy_manager_entry *entry = NULL;
1107 struct tomoyo_policy_manager_entry *ptr; 1107 struct tomoyo_policy_manager_entry *ptr;
1108 const struct tomoyo_path_info *saved_manager; 1108 const struct tomoyo_path_info *saved_manager;
1109 int error = -ENOMEM; 1109 int error = is_delete ? -ENOENT : -ENOMEM;
1110 bool is_domain = false; 1110 bool is_domain = false;
1111 1111
1112 if (tomoyo_is_domain_def(manager)) { 1112 if (tomoyo_is_domain_def(manager)) {
@@ -1120,29 +1120,25 @@ static int tomoyo_update_manager_entry(const char *manager,
1120 saved_manager = tomoyo_save_name(manager); 1120 saved_manager = tomoyo_save_name(manager);
1121 if (!saved_manager) 1121 if (!saved_manager)
1122 return -ENOMEM; 1122 return -ENOMEM;
1123 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 1123 if (!is_delete)
1124 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
1124 mutex_lock(&tomoyo_policy_lock); 1125 mutex_lock(&tomoyo_policy_lock);
1125 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) { 1126 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
1126 if (ptr->manager != saved_manager) 1127 if (ptr->manager != saved_manager)
1127 continue; 1128 continue;
1128 ptr->is_deleted = is_delete; 1129 ptr->is_deleted = is_delete;
1129 error = 0; 1130 error = 0;
1130 goto out; 1131 break;
1131 } 1132 }
1132 if (is_delete) { 1133 if (!is_delete && error && tomoyo_memory_ok(entry)) {
1133 error = -ENOENT; 1134 entry->manager = saved_manager;
1134 goto out; 1135 entry->is_domain = is_domain;
1136 list_add_tail_rcu(&entry->list, &tomoyo_policy_manager_list);
1137 entry = NULL;
1138 error = 0;
1135 } 1139 }
1136 if (!tomoyo_memory_ok(new_entry))
1137 goto out;
1138 new_entry->manager = saved_manager;
1139 new_entry->is_domain = is_domain;
1140 list_add_tail_rcu(&new_entry->list, &tomoyo_policy_manager_list);
1141 new_entry = NULL;
1142 error = 0;
1143 out:
1144 mutex_unlock(&tomoyo_policy_lock); 1140 mutex_unlock(&tomoyo_policy_lock);
1145 kfree(new_entry); 1141 kfree(entry);
1146 return error; 1142 return error;
1147} 1143}
1148 1144
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index ec612ae87b51..229de1e71a38 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -201,11 +201,11 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
201 const bool is_not, 201 const bool is_not,
202 const bool is_delete) 202 const bool is_delete)
203{ 203{
204 struct tomoyo_domain_initializer_entry *new_entry; 204 struct tomoyo_domain_initializer_entry *entry = NULL;
205 struct tomoyo_domain_initializer_entry *ptr; 205 struct tomoyo_domain_initializer_entry *ptr;
206 const struct tomoyo_path_info *saved_program; 206 const struct tomoyo_path_info *saved_program;
207 const struct tomoyo_path_info *saved_domainname = NULL; 207 const struct tomoyo_path_info *saved_domainname = NULL;
208 int error = -ENOMEM; 208 int error = is_delete ? -ENOENT : -ENOMEM;
209 bool is_last_name = false; 209 bool is_last_name = false;
210 210
211 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__)) 211 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
@@ -218,12 +218,13 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
218 return -EINVAL; 218 return -EINVAL;
219 saved_domainname = tomoyo_save_name(domainname); 219 saved_domainname = tomoyo_save_name(domainname);
220 if (!saved_domainname) 220 if (!saved_domainname)
221 return -ENOMEM; 221 goto out;
222 } 222 }
223 saved_program = tomoyo_save_name(program); 223 saved_program = tomoyo_save_name(program);
224 if (!saved_program) 224 if (!saved_program)
225 return -ENOMEM; 225 goto out;
226 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 226 if (!is_delete)
227 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
227 mutex_lock(&tomoyo_policy_lock); 228 mutex_lock(&tomoyo_policy_lock);
228 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) { 229 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
229 if (ptr->is_not != is_not || 230 if (ptr->is_not != is_not ||
@@ -232,24 +233,21 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
232 continue; 233 continue;
233 ptr->is_deleted = is_delete; 234 ptr->is_deleted = is_delete;
234 error = 0; 235 error = 0;
235 goto out; 236 break;
236 } 237 }
237 if (is_delete) { 238 if (!is_delete && error && tomoyo_memory_ok(entry)) {
238 error = -ENOENT; 239 entry->domainname = saved_domainname;
239 goto out; 240 entry->program = saved_program;
241 entry->is_not = is_not;
242 entry->is_last_name = is_last_name;
243 list_add_tail_rcu(&entry->list,
244 &tomoyo_domain_initializer_list);
245 entry = NULL;
246 error = 0;
240 } 247 }
241 if (!tomoyo_memory_ok(new_entry))
242 goto out;
243 new_entry->domainname = saved_domainname;
244 new_entry->program = saved_program;
245 new_entry->is_not = is_not;
246 new_entry->is_last_name = is_last_name;
247 list_add_tail_rcu(&new_entry->list, &tomoyo_domain_initializer_list);
248 new_entry = NULL;
249 error = 0;
250 out:
251 mutex_unlock(&tomoyo_policy_lock); 248 mutex_unlock(&tomoyo_policy_lock);
252 kfree(new_entry); 249 out:
250 kfree(entry);
253 return error; 251 return error;
254} 252}
255 253
@@ -419,11 +417,11 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
419 const bool is_not, 417 const bool is_not,
420 const bool is_delete) 418 const bool is_delete)
421{ 419{
422 struct tomoyo_domain_keeper_entry *new_entry; 420 struct tomoyo_domain_keeper_entry *entry = NULL;
423 struct tomoyo_domain_keeper_entry *ptr; 421 struct tomoyo_domain_keeper_entry *ptr;
424 const struct tomoyo_path_info *saved_domainname; 422 const struct tomoyo_path_info *saved_domainname;
425 const struct tomoyo_path_info *saved_program = NULL; 423 const struct tomoyo_path_info *saved_program = NULL;
426 int error = -ENOMEM; 424 int error = is_delete ? -ENOENT : -ENOMEM;
427 bool is_last_name = false; 425 bool is_last_name = false;
428 426
429 if (!tomoyo_is_domain_def(domainname) && 427 if (!tomoyo_is_domain_def(domainname) &&
@@ -436,12 +434,13 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
436 return -EINVAL; 434 return -EINVAL;
437 saved_program = tomoyo_save_name(program); 435 saved_program = tomoyo_save_name(program);
438 if (!saved_program) 436 if (!saved_program)
439 return -ENOMEM; 437 goto out;
440 } 438 }
441 saved_domainname = tomoyo_save_name(domainname); 439 saved_domainname = tomoyo_save_name(domainname);
442 if (!saved_domainname) 440 if (!saved_domainname)
443 return -ENOMEM; 441 goto out;
444 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 442 if (!is_delete)
443 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
445 mutex_lock(&tomoyo_policy_lock); 444 mutex_lock(&tomoyo_policy_lock);
446 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) { 445 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
447 if (ptr->is_not != is_not || 446 if (ptr->is_not != is_not ||
@@ -450,24 +449,20 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
450 continue; 449 continue;
451 ptr->is_deleted = is_delete; 450 ptr->is_deleted = is_delete;
452 error = 0; 451 error = 0;
453 goto out; 452 break;
454 } 453 }
455 if (is_delete) { 454 if (!is_delete && error && tomoyo_memory_ok(entry)) {
456