aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/common.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2009-12-07 19:34:43 -0500
committerJames Morris <jmorris@namei.org>2009-12-14 23:46:31 -0500
commitfdb8ebb729bbb640e64028a4f579a02ebc405727 (patch)
tree9dfca7422cb858cd05208734affab31d980030fe /security/tomoyo/common.c
parent86fc80f16e8a2449d5827bf1a9838b7fd9f70097 (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.c90
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 */
373struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) 372struct 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 */
833bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) 834bool 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 */
1100static int tomoyo_update_manager_entry(const char *manager, 1101static 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 */
1151static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head) 1154static 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 */
1170static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) 1175static 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 */
1200static bool tomoyo_is_policy_manager(void) 1205static 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 */
1256static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, 1259static 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 */
1311static int tomoyo_delete_domain(char *domainname) 1311static 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 */
1341static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) 1343static 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 */
1512static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) 1514static 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 */
1594static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) 1594static 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 */
1629static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) 1629static 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 */
1705static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) 1705static 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 */
1739static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) 1741static 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 */
1924static int tomoyo_open_control(const u8 type, struct file *file) 1926static 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 */
2030static int tomoyo_read_control(struct file *file, char __user *buffer, 2035static 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 */
2073static int tomoyo_write_control(struct file *file, const char __user *buffer, 2080static 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 */
2123static int tomoyo_close_control(struct file *file) 2132static 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;