diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2009-12-07 19:34:43 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2009-12-14 23:46:31 -0500 |
commit | fdb8ebb729bbb640e64028a4f579a02ebc405727 (patch) | |
tree | 9dfca7422cb858cd05208734affab31d980030fe /security/tomoyo/common.c | |
parent | 86fc80f16e8a2449d5827bf1a9838b7fd9f70097 (diff) |
TOMOYO: Use RCU primitives for list operation
Replace list operation with RCU primitives and replace
down_read()/up_read() with srcu_read_lock()/srcu_read_unlock().
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r-- | security/tomoyo/common.c | 90 |
1 files changed, 50 insertions, 40 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 6c606168243..f01b9364db2 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -365,10 +365,9 @@ bool tomoyo_is_domain_def(const unsigned char *buffer) | |||
365 | * | 365 | * |
366 | * @domainname: The domainname to find. | 366 | * @domainname: The domainname to find. |
367 | * | 367 | * |
368 | * Caller must call down_read(&tomoyo_domain_list_lock); or | ||
369 | * down_write(&tomoyo_domain_list_lock); . | ||
370 | * | ||
371 | * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise. | 368 | * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise. |
369 | * | ||
370 | * Caller holds tomoyo_read_lock(). | ||
372 | */ | 371 | */ |
373 | struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) | 372 | struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) |
374 | { | 373 | { |
@@ -377,7 +376,7 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) | |||
377 | 376 | ||
378 | name.name = domainname; | 377 | name.name = domainname; |
379 | tomoyo_fill_path_info(&name); | 378 | tomoyo_fill_path_info(&name); |
380 | list_for_each_entry(domain, &tomoyo_domain_list, list) { | 379 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { |
381 | if (!domain->is_deleted && | 380 | if (!domain->is_deleted && |
382 | !tomoyo_pathcmp(&name, domain->domainname)) | 381 | !tomoyo_pathcmp(&name, domain->domainname)) |
383 | return domain; | 382 | return domain; |
@@ -829,6 +828,8 @@ bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain) | |||
829 | * @domain: Pointer to "struct tomoyo_domain_info". | 828 | * @domain: Pointer to "struct tomoyo_domain_info". |
830 | * | 829 | * |
831 | * Returns true if the domain is not exceeded quota, false otherwise. | 830 | * Returns true if the domain is not exceeded quota, false otherwise. |
831 | * | ||
832 | * Caller holds tomoyo_read_lock(). | ||
832 | */ | 833 | */ |
833 | bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) | 834 | bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) |
834 | { | 835 | { |
@@ -837,8 +838,7 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) | |||
837 | 838 | ||
838 | if (!domain) | 839 | if (!domain) |
839 | return true; | 840 | return true; |
840 | down_read(&tomoyo_domain_acl_info_list_lock); | 841 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { |
841 | list_for_each_entry(ptr, &domain->acl_info_list, list) { | ||
842 | if (ptr->type & TOMOYO_ACL_DELETED) | 842 | if (ptr->type & TOMOYO_ACL_DELETED) |
843 | continue; | 843 | continue; |
844 | switch (tomoyo_acl_type2(ptr)) { | 844 | switch (tomoyo_acl_type2(ptr)) { |
@@ -866,7 +866,6 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) | |||
866 | break; | 866 | break; |
867 | } | 867 | } |
868 | } | 868 | } |
869 | up_read(&tomoyo_domain_acl_info_list_lock); | ||
870 | if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY)) | 869 | if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY)) |
871 | return true; | 870 | return true; |
872 | if (!domain->quota_warned) { | 871 | if (!domain->quota_warned) { |
@@ -1096,6 +1095,8 @@ static DECLARE_RWSEM(tomoyo_policy_manager_list_lock); | |||
1096 | * @is_delete: True if it is a delete request. | 1095 | * @is_delete: True if it is a delete request. |
1097 | * | 1096 | * |
1098 | * Returns 0 on success, negative value otherwise. | 1097 | * Returns 0 on success, negative value otherwise. |
1098 | * | ||
1099 | * Caller holds tomoyo_read_lock(). | ||
1099 | */ | 1100 | */ |
1100 | static int tomoyo_update_manager_entry(const char *manager, | 1101 | static int tomoyo_update_manager_entry(const char *manager, |
1101 | const bool is_delete) | 1102 | const bool is_delete) |
@@ -1118,7 +1119,7 @@ static int tomoyo_update_manager_entry(const char *manager, | |||
1118 | if (!saved_manager) | 1119 | if (!saved_manager) |
1119 | return -ENOMEM; | 1120 | return -ENOMEM; |
1120 | down_write(&tomoyo_policy_manager_list_lock); | 1121 | down_write(&tomoyo_policy_manager_list_lock); |
1121 | list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { | 1122 | list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) { |
1122 | if (ptr->manager != saved_manager) | 1123 | if (ptr->manager != saved_manager) |
1123 | continue; | 1124 | continue; |
1124 | ptr->is_deleted = is_delete; | 1125 | ptr->is_deleted = is_delete; |
@@ -1134,7 +1135,7 @@ static int tomoyo_update_manager_entry(const char *manager, | |||
1134 | goto out; | 1135 | goto out; |
1135 | new_entry->manager = saved_manager; | 1136 | new_entry->manager = saved_manager; |
1136 | new_entry->is_domain = is_domain; | 1137 | new_entry->is_domain = is_domain; |
1137 | list_add_tail(&new_entry->list, &tomoyo_policy_manager_list); | 1138 | list_add_tail_rcu(&new_entry->list, &tomoyo_policy_manager_list); |
1138 | error = 0; | 1139 | error = 0; |
1139 | out: | 1140 | out: |
1140 | up_write(&tomoyo_policy_manager_list_lock); | 1141 | up_write(&tomoyo_policy_manager_list_lock); |
@@ -1147,6 +1148,8 @@ static int tomoyo_update_manager_entry(const char *manager, | |||
1147 | * @head: Pointer to "struct tomoyo_io_buffer". | 1148 | * @head: Pointer to "struct tomoyo_io_buffer". |
1148 | * | 1149 | * |
1149 | * Returns 0 on success, negative value otherwise. | 1150 | * Returns 0 on success, negative value otherwise. |
1151 | * | ||
1152 | * Caller holds tomoyo_read_lock(). | ||
1150 | */ | 1153 | */ |
1151 | static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head) | 1154 | static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head) |
1152 | { | 1155 | { |
@@ -1166,6 +1169,8 @@ static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head) | |||
1166 | * @head: Pointer to "struct tomoyo_io_buffer". | 1169 | * @head: Pointer to "struct tomoyo_io_buffer". |
1167 | * | 1170 | * |
1168 | * Returns 0. | 1171 | * Returns 0. |
1172 | * | ||
1173 | * Caller holds tomoyo_read_lock(). | ||
1169 | */ | 1174 | */ |
1170 | static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) | 1175 | static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) |
1171 | { | 1176 | { |
@@ -1174,7 +1179,6 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) | |||
1174 | 1179 | ||
1175 | if (head->read_eof) | 1180 | if (head->read_eof) |
1176 | return 0; | 1181 | return 0; |
1177 | down_read(&tomoyo_policy_manager_list_lock); | ||
1178 | list_for_each_cookie(pos, head->read_var2, | 1182 | list_for_each_cookie(pos, head->read_var2, |
1179 | &tomoyo_policy_manager_list) { | 1183 | &tomoyo_policy_manager_list) { |
1180 | struct tomoyo_policy_manager_entry *ptr; | 1184 | struct tomoyo_policy_manager_entry *ptr; |
@@ -1186,7 +1190,6 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) | |||
1186 | if (!done) | 1190 | if (!done) |
1187 | break; | 1191 | break; |
1188 | } | 1192 | } |
1189 | up_read(&tomoyo_policy_manager_list_lock); | ||
1190 | head->read_eof = done; | 1193 | head->read_eof = done; |
1191 | return 0; | 1194 | return 0; |
1192 | } | 1195 | } |
@@ -1196,6 +1199,8 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) | |||
1196 | * | 1199 | * |
1197 | * Returns true if the current process is permitted to modify policy | 1200 | * Returns true if the current process is permitted to modify policy |
1198 | * via /sys/kernel/security/tomoyo/ interface. | 1201 | * via /sys/kernel/security/tomoyo/ interface. |
1202 | * | ||
1203 | * Caller holds tomoyo_read_lock(). | ||
1199 | */ | 1204 | */ |
1200 | static bool tomoyo_is_policy_manager(void) | 1205 | static bool tomoyo_is_policy_manager(void) |
1201 | { | 1206 | { |
@@ -1209,29 +1214,25 @@ static bool tomoyo_is_policy_manager(void) | |||
1209 | return true; | 1214 | return true; |
1210 | if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) | 1215 | if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) |
1211 | return false; | 1216 | return false; |
1212 | down_read(&tomoyo_policy_manager_list_lock); | 1217 | list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) { |
1213 | list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { | ||
1214 | if (!ptr->is_deleted && ptr->is_domain | 1218 | if (!ptr->is_deleted && ptr->is_domain |
1215 | && !tomoyo_pathcmp(domainname, ptr->manager)) { | 1219 | && !tomoyo_pathcmp(domainname, ptr->manager)) { |
1216 | found = true; | 1220 | found = true; |
1217 | break; | 1221 | break; |
1218 | } | 1222 | } |
1219 | } | 1223 | } |
1220 | up_read(&tomoyo_policy_manager_list_lock); | ||
1221 | if (found) | 1224 | if (found) |
1222 | return true; | 1225 | return true; |
1223 | exe = tomoyo_get_exe(); | 1226 | exe = tomoyo_get_exe(); |
1224 | if (!exe) | 1227 | if (!exe) |
1225 | return false; | 1228 | return false; |
1226 | down_read(&tomoyo_policy_manager_list_lock); | 1229 | list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) { |
1227 | list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { | ||
1228 | if (!ptr->is_deleted && !ptr->is_domain | 1230 | if (!ptr->is_deleted && !ptr->is_domain |
1229 | && !strcmp(exe, ptr->manager->name)) { | 1231 | && !strcmp(exe, ptr->manager->name)) { |
1230 | found = true; | 1232 | found = true; |
1231 | break; | 1233 | break; |
1232 | } | 1234 | } |
1233 | } | 1235 | } |
1234 | up_read(&tomoyo_policy_manager_list_lock); | ||
1235 | if (!found) { /* Reduce error messages. */ | 1236 | if (!found) { /* Reduce error messages. */ |
1236 | static pid_t last_pid; | 1237 | static pid_t last_pid; |
1237 | const pid_t pid = current->pid; | 1238 | const pid_t pid = current->pid; |
@@ -1252,6 +1253,8 @@ static bool tomoyo_is_policy_manager(void) | |||
1252 | * @data: String to parse. | 1253 | * @data: String to parse. |
1253 | * | 1254 | * |
1254 | * Returns true on success, false otherwise. | 1255 | * Returns true on success, false otherwise. |
1256 | * | ||
1257 | * Caller holds tomoyo_read_lock(). | ||
1255 | */ | 1258 | */ |
1256 | static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, | 1259 | static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, |
1257 | const char *data) | 1260 | const char *data) |
@@ -1267,11 +1270,8 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, | |||
1267 | domain = tomoyo_real_domain(p); | 1270 | domain = tomoyo_real_domain(p); |
1268 | read_unlock(&tasklist_lock); | 1271 | read_unlock(&tasklist_lock); |
1269 | } else if (!strncmp(data, "domain=", 7)) { | 1272 | } else if (!strncmp(data, "domain=", 7)) { |
1270 | if (tomoyo_is_domain_def(data + 7)) { | 1273 | if (tomoyo_is_domain_def(data + 7)) |
1271 | down_read(&tomoyo_domain_list_lock); | ||
1272 | domain = tomoyo_find_domain(data + 7); | 1274 | domain = tomoyo_find_domain(data + 7); |
1273 | up_read(&tomoyo_domain_list_lock); | ||
1274 | } | ||
1275 | } else | 1275 | } else |
1276 | return false; | 1276 | return false; |
1277 | head->write_var1 = domain; | 1277 | head->write_var1 = domain; |
@@ -1285,13 +1285,11 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, | |||
1285 | if (domain) { | 1285 | if (domain) { |
1286 | struct tomoyo_domain_info *d; | 1286 | struct tomoyo_domain_info *d; |
1287 | head->read_var1 = NULL; | 1287 | head->read_var1 = NULL; |
1288 | down_read(&tomoyo_domain_list_lock); | 1288 | list_for_each_entry_rcu(d, &tomoyo_domain_list, list) { |
1289 | list_for_each_entry(d, &tomoyo_domain_list, list) { | ||
1290 | if (d == domain) | 1289 | if (d == domain) |
1291 | break; | 1290 | break; |
1292 | head->read_var1 = &d->list; | 1291 | head->read_var1 = &d->list; |
1293 | } | 1292 | } |
1294 | up_read(&tomoyo_domain_list_lock); | ||
1295 | head->read_var2 = NULL; | 1293 | head->read_var2 = NULL; |
1296 | head->read_bit = 0; | 1294 | head->read_bit = 0; |
1297 | head->read_step = 0; | 1295 | head->read_step = 0; |
@@ -1307,6 +1305,8 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, | |||
1307 | * @domainname: The name of domain. | 1305 | * @domainname: The name of domain. |
1308 | * | 1306 | * |
1309 | * Returns 0. | 1307 | * Returns 0. |
1308 | * | ||
1309 | * Caller holds tomoyo_read_lock(). | ||
1310 | */ | 1310 | */ |
1311 | static int tomoyo_delete_domain(char *domainname) | 1311 | static int tomoyo_delete_domain(char *domainname) |
1312 | { | 1312 | { |
@@ -1317,7 +1317,7 @@ static int tomoyo_delete_domain(char *domainname) | |||
1317 | tomoyo_fill_path_info(&name); | 1317 | tomoyo_fill_path_info(&name); |
1318 | down_write(&tomoyo_domain_list_lock); | 1318 | down_write(&tomoyo_domain_list_lock); |
1319 | /* Is there an active domain? */ | 1319 | /* Is there an active domain? */ |
1320 | list_for_each_entry(domain, &tomoyo_domain_list, list) { | 1320 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { |
1321 | /* Never delete tomoyo_kernel_domain */ | 1321 | /* Never delete tomoyo_kernel_domain */ |
1322 | if (domain == &tomoyo_kernel_domain) | 1322 | if (domain == &tomoyo_kernel_domain) |
1323 | continue; | 1323 | continue; |
@@ -1337,6 +1337,8 @@ static int tomoyo_delete_domain(char *domainname) | |||
1337 | * @head: Pointer to "struct tomoyo_io_buffer". | 1337 | * @head: Pointer to "struct tomoyo_io_buffer". |
1338 | * | 1338 | * |
1339 | * Returns 0 on success, negative value otherwise. | 1339 | * Returns 0 on success, negative value otherwise. |
1340 | * | ||
1341 | * Caller holds tomoyo_read_lock(). | ||
1340 | */ | 1342 | */ |
1341 | static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) | 1343 | static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) |
1342 | { | 1344 | { |
@@ -1359,11 +1361,9 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) | |||
1359 | domain = NULL; | 1361 | domain = NULL; |
1360 | if (is_delete) | 1362 | if (is_delete) |
1361 | tomoyo_delete_domain(data); | 1363 | tomoyo_delete_domain(data); |
1362 | else if (is_select) { | 1364 | else if (is_select) |
1363 | down_read(&tomoyo_domain_list_lock); | ||
1364 | domain = tomoyo_find_domain(data); | 1365 | domain = tomoyo_find_domain(data); |
1365 | up_read(&tomoyo_domain_list_lock); | 1366 | else |
1366 | } else | ||
1367 | domain = tomoyo_find_or_assign_new_domain(data, 0); | 1367 | domain = tomoyo_find_or_assign_new_domain(data, 0); |
1368 | head->write_var1 = domain; | 1368 | head->write_var1 = domain; |
1369 | return 0; | 1369 | return 0; |
@@ -1508,6 +1508,8 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1508 | * @head: Pointer to "struct tomoyo_io_buffer". | 1508 | * @head: Pointer to "struct tomoyo_io_buffer". |
1509 | * | 1509 | * |
1510 | * Returns 0. | 1510 | * Returns 0. |
1511 | * | ||
1512 | * Caller holds tomoyo_read_lock(). | ||
1511 | */ | 1513 | */ |
1512 | static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) | 1514 | static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) |
1513 | { | 1515 | { |
@@ -1519,7 +1521,6 @@ static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) | |||
1519 | return 0; | 1521 | return 0; |
1520 | if (head->read_step == 0) | 1522 | if (head->read_step == 0) |
1521 | head->read_step = 1; | 1523 | head->read_step = 1; |
1522 | down_read(&tomoyo_domain_list_lock); | ||
1523 | list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) { | 1524 | list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) { |
1524 | struct tomoyo_domain_info *domain; | 1525 | struct tomoyo_domain_info *domain; |
1525 | const char *quota_exceeded = ""; | 1526 | const char *quota_exceeded = ""; |
@@ -1552,7 +1553,6 @@ acl_loop: | |||
1552 | if (head->read_step == 3) | 1553 | if (head->read_step == 3) |
1553 | goto tail_mark; | 1554 | goto tail_mark; |
1554 | /* Print ACL entries in the domain. */ | 1555 | /* Print ACL entries in the domain. */ |
1555 | down_read(&tomoyo_domain_acl_info_list_lock); | ||
1556 | list_for_each_cookie(apos, head->read_var2, | 1556 | list_for_each_cookie(apos, head->read_var2, |
1557 | &domain->acl_info_list) { | 1557 | &domain->acl_info_list) { |
1558 | struct tomoyo_acl_info *ptr | 1558 | struct tomoyo_acl_info *ptr |
@@ -1562,7 +1562,6 @@ acl_loop: | |||
1562 | if (!done) | 1562 | if (!done) |
1563 | break; | 1563 | break; |
1564 | } | 1564 | } |
1565 | up_read(&tomoyo_domain_acl_info_list_lock); | ||
1566 | if (!done) | 1565 | if (!done) |
1567 | break; | 1566 | break; |
1568 | head->read_step = 3; | 1567 | head->read_step = 3; |
@@ -1574,7 +1573,6 @@ tail_mark: | |||
1574 | if (head->read_single_domain) | 1573 | if (head->read_single_domain) |
1575 | break; | 1574 | break; |
1576 | } | 1575 | } |
1577 | up_read(&tomoyo_domain_list_lock); | ||
1578 | head->read_eof = done; | 1576 | head->read_eof = done; |
1579 | return 0; | 1577 | return 0; |
1580 | } | 1578 | } |
@@ -1590,6 +1588,8 @@ tail_mark: | |||
1590 | * | 1588 | * |
1591 | * ( echo "select " $domainname; echo "use_profile " $profile ) | | 1589 | * ( echo "select " $domainname; echo "use_profile " $profile ) | |
1592 | * /usr/lib/ccs/loadpolicy -d | 1590 | * /usr/lib/ccs/loadpolicy -d |
1591 | * | ||
1592 | * Caller holds tomoyo_read_lock(). | ||
1593 | */ | 1593 | */ |
1594 | static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) | 1594 | static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) |
1595 | { | 1595 | { |
@@ -1601,9 +1601,7 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) | |||
1601 | if (!cp) | 1601 | if (!cp) |
1602 | return -EINVAL; | 1602 | return -EINVAL; |
1603 | *cp = '\0'; | 1603 | *cp = '\0'; |
1604 | down_read(&tomoyo_domain_list_lock); | ||
1605 | domain = tomoyo_find_domain(cp + 1); | 1604 | domain = tomoyo_find_domain(cp + 1); |
1606 | up_read(&tomoyo_domain_list_lock); | ||
1607 | if (strict_strtoul(data, 10, &profile)) | 1605 | if (strict_strtoul(data, 10, &profile)) |
1608 | return -EINVAL; | 1606 | return -EINVAL; |
1609 | if (domain && profile < TOMOYO_MAX_PROFILES | 1607 | if (domain && profile < TOMOYO_MAX_PROFILES |
@@ -1625,6 +1623,8 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) | |||
1625 | * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" ) | 1623 | * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" ) |
1626 | * domainname = $0; } else if ( $1 == "use_profile" ) { | 1624 | * domainname = $0; } else if ( $1 == "use_profile" ) { |
1627 | * print $2 " " domainname; domainname = ""; } } ; ' | 1625 | * print $2 " " domainname; domainname = ""; } } ; ' |
1626 | * | ||
1627 | * Caller holds tomoyo_read_lock(). | ||
1628 | */ | 1628 | */ |
1629 | static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) | 1629 | static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) |
1630 | { | 1630 | { |
@@ -1633,7 +1633,6 @@ static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) | |||
1633 | 1633 | ||
1634 | if (head->read_eof) | 1634 | if (head->read_eof) |
1635 | return 0; | 1635 | return 0; |
1636 | down_read(&tomoyo_domain_list_lock); | ||
1637 | list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) { | 1636 | list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) { |
1638 | struct tomoyo_domain_info *domain; | 1637 | struct tomoyo_domain_info *domain; |
1639 | domain = list_entry(pos, struct tomoyo_domain_info, list); | 1638 | domain = list_entry(pos, struct tomoyo_domain_info, list); |
@@ -1644,7 +1643,6 @@ static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) | |||
1644 | if (!done) | 1643 | if (!done) |
1645 | break; | 1644 | break; |
1646 | } | 1645 | } |
1647 | up_read(&tomoyo_domain_list_lock); | ||
1648 | head->read_eof = done; | 1646 | head->read_eof = done; |
1649 | return 0; | 1647 | return 0; |
1650 | } | 1648 | } |
@@ -1701,6 +1699,8 @@ static int tomoyo_read_pid(struct tomoyo_io_buffer *head) | |||
1701 | * @head: Pointer to "struct tomoyo_io_buffer". | 1699 | * @head: Pointer to "struct tomoyo_io_buffer". |
1702 | * | 1700 | * |
1703 | * Returns 0 on success, negative value otherwise. | 1701 | * Returns 0 on success, negative value otherwise. |
1702 | * | ||
1703 | * Caller holds tomoyo_read_lock(). | ||
1704 | */ | 1704 | */ |
1705 | static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) | 1705 | static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) |
1706 | { | 1706 | { |
@@ -1735,6 +1735,8 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) | |||
1735 | * @head: Pointer to "struct tomoyo_io_buffer". | 1735 | * @head: Pointer to "struct tomoyo_io_buffer". |
1736 | * | 1736 | * |
1737 | * Returns 0 on success, -EINVAL otherwise. | 1737 | * Returns 0 on success, -EINVAL otherwise. |
1738 | * | ||
1739 | * Caller holds tomoyo_read_lock(). | ||
1738 | */ | 1740 | */ |
1739 | static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) | 1741 | static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) |
1740 | { | 1742 | { |
@@ -1864,15 +1866,13 @@ void tomoyo_load_policy(const char *filename) | |||
1864 | tomoyo_policy_loaded = true; | 1866 | tomoyo_policy_loaded = true; |
1865 | { /* Check all profiles currently assigned to domains are defined. */ | 1867 | { /* Check all profiles currently assigned to domains are defined. */ |
1866 | struct tomoyo_domain_info *domain; | 1868 | struct tomoyo_domain_info *domain; |
1867 | down_read(&tomoyo_domain_list_lock); | 1869 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { |
1868 | list_for_each_entry(domain, &tomoyo_domain_list, list) { | ||
1869 | const u8 profile = domain->profile; | 1870 | const u8 profile = domain->profile; |
1870 | if (tomoyo_profile_ptr[profile]) | 1871 | if (tomoyo_profile_ptr[profile]) |
1871 | continue; | 1872 | continue; |
1872 | panic("Profile %u (used by '%s') not defined.\n", | 1873 | panic("Profile %u (used by '%s') not defined.\n", |
1873 | profile, domain->domainname->name); | 1874 | profile, domain->domainname->name); |
1874 | } | 1875 | } |
1875 | up_read(&tomoyo_domain_list_lock); | ||
1876 | } | 1876 | } |
1877 | } | 1877 | } |
1878 | 1878 | ||
@@ -1920,6 +1920,8 @@ static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head) | |||
1920 | * @file: Pointer to "struct file". | 1920 | * @file: Pointer to "struct file". |
1921 | * | 1921 | * |
1922 | * Associates policy handler and returns 0 on success, -ENOMEM otherwise. | 1922 | * Associates policy handler and returns 0 on success, -ENOMEM otherwise. |
1923 | * | ||
1924 | * Caller acquires tomoyo_read_lock(). | ||
1923 | */ | 1925 | */ |
1924 | static int tomoyo_open_control(const u8 type, struct file *file) | 1926 | static int tomoyo_open_control(const u8 type, struct file *file) |
1925 | { | 1927 | { |
@@ -2005,6 +2007,7 @@ static int tomoyo_open_control(const u8 type, struct file *file) | |||
2005 | return -ENOMEM; | 2007 | return -ENOMEM; |
2006 | } | 2008 | } |
2007 | } | 2009 | } |
2010 | head->reader_idx = tomoyo_read_lock(); | ||
2008 | file->private_data = head; | 2011 | file->private_data = head; |
2009 | /* | 2012 | /* |
2010 | * Call the handler now if the file is | 2013 | * Call the handler now if the file is |
@@ -2026,6 +2029,8 @@ static int tomoyo_open_control(const u8 type, struct file *file) | |||
2026 | * @buffer_len: Size of @buffer. | 2029 | * @buffer_len: Size of @buffer. |
2027 | * | 2030 | * |
2028 | * Returns bytes read on success, negative value otherwise. | 2031 | * Returns bytes read on success, negative value otherwise. |
2032 | * | ||
2033 | * Caller holds tomoyo_read_lock(). | ||
2029 | */ | 2034 | */ |
2030 | static int tomoyo_read_control(struct file *file, char __user *buffer, | 2035 | static int tomoyo_read_control(struct file *file, char __user *buffer, |
2031 | const int buffer_len) | 2036 | const int buffer_len) |
@@ -2069,6 +2074,8 @@ static int tomoyo_read_control(struct file *file, char __user *buffer, | |||
2069 | * @buffer_len: Size of @buffer. | 2074 | * @buffer_len: Size of @buffer. |
2070 | * | 2075 | * |
2071 | * Returns @buffer_len on success, negative value otherwise. | 2076 | * Returns @buffer_len on success, negative value otherwise. |
2077 | * | ||
2078 | * Caller holds tomoyo_read_lock(). | ||
2072 | */ | 2079 | */ |
2073 | static int tomoyo_write_control(struct file *file, const char __user *buffer, | 2080 | static int tomoyo_write_control(struct file *file, const char __user *buffer, |
2074 | const int buffer_len) | 2081 | const int buffer_len) |
@@ -2119,11 +2126,14 @@ static int tomoyo_write_control(struct file *file, const char __user *buffer, | |||
2119 | * @file: Pointer to "struct file". | 2126 | * @file: Pointer to "struct file". |
2120 | * | 2127 | * |
2121 | * Releases memory and returns 0. | 2128 | * Releases memory and returns 0. |
2129 | * | ||
2130 | * Caller looses tomoyo_read_lock(). | ||
2122 | */ | 2131 | */ |
2123 | static int tomoyo_close_control(struct file *file) | 2132 | static int tomoyo_close_control(struct file *file) |
2124 | { | 2133 | { |
2125 | struct tomoyo_io_buffer *head = file->private_data; | 2134 | struct tomoyo_io_buffer *head = file->private_data; |
2126 | 2135 | ||
2136 | tomoyo_read_unlock(head->reader_idx); | ||
2127 | /* Release memory used for policy I/O. */ | 2137 | /* Release memory used for policy I/O. */ |
2128 | tomoyo_free(head->read_buf); | 2138 | tomoyo_free(head->read_buf); |
2129 | head->read_buf = NULL; | 2139 | head->read_buf = NULL; |