aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-07-19 03:39:19 -0400
committerJames Morris <james.l.morris@oracle.com>2014-07-19 03:39:19 -0400
commit2ccf4661f315615d018686d91d030a94001d0cc6 (patch)
treef5374b5233ba5c43a4710bc8cbc5319091da044e /security
parent32c2e6752ff0f48fe03b9e1c7c64bde580a840d2 (diff)
parent615e51fdda6f274e94b1e905fcaf6111e0d9aa20 (diff)
Merge branch 'next' of git://git.infradead.org/users/pcmoore/selinux into next
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c14
-rw-r--r--security/selinux/include/netif.h2
-rw-r--r--security/selinux/include/netnode.h2
-rw-r--r--security/selinux/include/netport.h2
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/netif.c15
-rw-r--r--security/selinux/netnode.c15
-rw-r--r--security/selinux/netport.c15
-rw-r--r--security/selinux/ss/conditional.c11
-rw-r--r--security/selinux/ss/policydb.c141
-rw-r--r--security/selinux/ss/services.c41
11 files changed, 101 insertions, 160 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index a1ac1c5c729b..7740f61588d6 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -161,6 +161,17 @@ static int selinux_peerlbl_enabled(void)
161 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled()); 161 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
162} 162}
163 163
164static int selinux_netcache_avc_callback(u32 event)
165{
166 if (event == AVC_CALLBACK_RESET) {
167 sel_netif_flush();
168 sel_netnode_flush();
169 sel_netport_flush();
170 synchronize_net();
171 }
172 return 0;
173}
174
164/* 175/*
165 * initialise the security for the init task 176 * initialise the security for the init task
166 */ 177 */
@@ -6002,6 +6013,9 @@ static __init int selinux_init(void)
6002 if (register_security(&selinux_ops)) 6013 if (register_security(&selinux_ops))
6003 panic("SELinux: Unable to register with kernel.\n"); 6014 panic("SELinux: Unable to register with kernel.\n");
6004 6015
6016 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6017 panic("SELinux: Unable to register AVC netcache callback\n");
6018
6005 if (selinux_enforcing) 6019 if (selinux_enforcing)
6006 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n"); 6020 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
6007 else 6021 else
diff --git a/security/selinux/include/netif.h b/security/selinux/include/netif.h
index 43d507242b42..57c6eae81eac 100644
--- a/security/selinux/include/netif.h
+++ b/security/selinux/include/netif.h
@@ -17,6 +17,8 @@
17#ifndef _SELINUX_NETIF_H_ 17#ifndef _SELINUX_NETIF_H_
18#define _SELINUX_NETIF_H_ 18#define _SELINUX_NETIF_H_
19 19
20void sel_netif_flush(void);
21
20int sel_netif_sid(int ifindex, u32 *sid); 22int sel_netif_sid(int ifindex, u32 *sid);
21 23
22#endif /* _SELINUX_NETIF_H_ */ 24#endif /* _SELINUX_NETIF_H_ */
diff --git a/security/selinux/include/netnode.h b/security/selinux/include/netnode.h
index df7a5ed6c694..937668dd3024 100644
--- a/security/selinux/include/netnode.h
+++ b/security/selinux/include/netnode.h
@@ -27,6 +27,8 @@
27#ifndef _SELINUX_NETNODE_H 27#ifndef _SELINUX_NETNODE_H
28#define _SELINUX_NETNODE_H 28#define _SELINUX_NETNODE_H
29 29
30void sel_netnode_flush(void);
31
30int sel_netnode_sid(void *addr, u16 family, u32 *sid); 32int sel_netnode_sid(void *addr, u16 family, u32 *sid);
31 33
32#endif 34#endif
diff --git a/security/selinux/include/netport.h b/security/selinux/include/netport.h
index 4d965b83d735..d1ce896b2cb0 100644
--- a/security/selinux/include/netport.h
+++ b/security/selinux/include/netport.h
@@ -26,6 +26,8 @@
26#ifndef _SELINUX_NETPORT_H 26#ifndef _SELINUX_NETPORT_H
27#define _SELINUX_NETPORT_H 27#define _SELINUX_NETPORT_H
28 28
29void sel_netport_flush(void);
30
29int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid); 31int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid);
30 32
31#endif 33#endif
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index ce7852cf526b..d1e0b239b602 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -8,6 +8,7 @@
8#ifndef _SELINUX_SECURITY_H_ 8#ifndef _SELINUX_SECURITY_H_
9#define _SELINUX_SECURITY_H_ 9#define _SELINUX_SECURITY_H_
10 10
11#include <linux/compiler.h>
11#include <linux/dcache.h> 12#include <linux/dcache.h>
12#include <linux/magic.h> 13#include <linux/magic.h>
13#include <linux/types.h> 14#include <linux/types.h>
@@ -220,7 +221,7 @@ struct selinux_kernel_status {
220 /* 221 /*
221 * The version > 0 supports above members. 222 * The version > 0 supports above members.
222 */ 223 */
223} __attribute__((packed)); 224} __packed;
224 225
225extern void selinux_status_update_setenforce(int enforcing); 226extern void selinux_status_update_setenforce(int enforcing);
226extern void selinux_status_update_policyload(int seqno); 227extern void selinux_status_update_policyload(int seqno);
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index 694e9e43855f..3c3de4ca0ebc 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -240,7 +240,7 @@ static void sel_netif_kill(int ifindex)
240 * Remove all entries from the network interface table. 240 * Remove all entries from the network interface table.
241 * 241 *
242 */ 242 */
243static void sel_netif_flush(void) 243void sel_netif_flush(void)
244{ 244{
245 int idx; 245 int idx;
246 struct sel_netif *netif; 246 struct sel_netif *netif;
@@ -252,15 +252,6 @@ static void sel_netif_flush(void)
252 spin_unlock_bh(&sel_netif_lock); 252 spin_unlock_bh(&sel_netif_lock);
253} 253}
254 254
255static int sel_netif_avc_callback(u32 event)
256{
257 if (event == AVC_CALLBACK_RESET) {
258 sel_netif_flush();
259 synchronize_net();
260 }
261 return 0;
262}
263
264static int sel_netif_netdev_notifier_handler(struct notifier_block *this, 255static int sel_netif_netdev_notifier_handler(struct notifier_block *this,
265 unsigned long event, void *ptr) 256 unsigned long event, void *ptr)
266{ 257{
@@ -291,10 +282,6 @@ static __init int sel_netif_init(void)
291 282
292 register_netdevice_notifier(&sel_netif_netdev_notifier); 283 register_netdevice_notifier(&sel_netif_netdev_notifier);
293 284
294 err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET);
295 if (err)
296 panic("avc_add_callback() failed, error %d\n", err);
297
298 return err; 285 return err;
299} 286}
300 287
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 03a72c32afd7..ddf315260839 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -283,7 +283,7 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid)
283 * Remove all entries from the network address table. 283 * Remove all entries from the network address table.
284 * 284 *
285 */ 285 */
286static void sel_netnode_flush(void) 286void sel_netnode_flush(void)
287{ 287{
288 unsigned int idx; 288 unsigned int idx;
289 struct sel_netnode *node, *node_tmp; 289 struct sel_netnode *node, *node_tmp;
@@ -300,15 +300,6 @@ static void sel_netnode_flush(void)
300 spin_unlock_bh(&sel_netnode_lock); 300 spin_unlock_bh(&sel_netnode_lock);
301} 301}
302 302
303static int sel_netnode_avc_callback(u32 event)
304{
305 if (event == AVC_CALLBACK_RESET) {
306 sel_netnode_flush();
307 synchronize_net();
308 }
309 return 0;
310}
311
312static __init int sel_netnode_init(void) 303static __init int sel_netnode_init(void)
313{ 304{
314 int iter; 305 int iter;
@@ -322,10 +313,6 @@ static __init int sel_netnode_init(void)
322 sel_netnode_hash[iter].size = 0; 313 sel_netnode_hash[iter].size = 0;
323 } 314 }
324 315
325 ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET);
326 if (ret != 0)
327 panic("avc_add_callback() failed, error %d\n", ret);
328
329 return ret; 316 return ret;
330} 317}
331 318
diff --git a/security/selinux/netport.c b/security/selinux/netport.c
index d35379781c2c..73ac6784d091 100644
--- a/security/selinux/netport.c
+++ b/security/selinux/netport.c
@@ -217,7 +217,7 @@ int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid)
217 * Remove all entries from the network address table. 217 * Remove all entries from the network address table.
218 * 218 *
219 */ 219 */
220static void sel_netport_flush(void) 220void sel_netport_flush(void)
221{ 221{
222 unsigned int idx; 222 unsigned int idx;
223 struct sel_netport *port, *port_tmp; 223 struct sel_netport *port, *port_tmp;
@@ -234,15 +234,6 @@ static void sel_netport_flush(void)
234 spin_unlock_bh(&sel_netport_lock); 234 spin_unlock_bh(&sel_netport_lock);
235} 235}
236 236
237static int sel_netport_avc_callback(u32 event)
238{
239 if (event == AVC_CALLBACK_RESET) {
240 sel_netport_flush();
241 synchronize_net();
242 }
243 return 0;
244}
245
246static __init int sel_netport_init(void) 237static __init int sel_netport_init(void)
247{ 238{
248 int iter; 239 int iter;
@@ -256,10 +247,6 @@ static __init int sel_netport_init(void)
256 sel_netport_hash[iter].size = 0; 247 sel_netport_hash[iter].size = 0;
257 } 248 }
258 249
259 ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET);
260 if (ret != 0)
261 panic("avc_add_callback() failed, error %d\n", ret);
262
263 return ret; 250 return ret;
264} 251}
265 252
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 377d148e7157..62c6773be0b7 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -402,19 +402,14 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
402 int rc; 402 int rc;
403 struct cond_expr *expr = NULL, *last = NULL; 403 struct cond_expr *expr = NULL, *last = NULL;
404 404
405 rc = next_entry(buf, fp, sizeof(u32)); 405 rc = next_entry(buf, fp, sizeof(u32) * 2);
406 if (rc) 406 if (rc)
407 return rc; 407 goto err;
408 408
409 node->cur_state = le32_to_cpu(buf[0]); 409 node->cur_state = le32_to_cpu(buf[0]);
410 410
411 len = 0;
412 rc = next_entry(buf, fp, sizeof(u32));
413 if (rc)
414 return rc;
415
416 /* expr */ 411 /* expr */
417 len = le32_to_cpu(buf[0]); 412 len = le32_to_cpu(buf[1]);
418 413
419 for (i = 0; i < len; i++) { 414 for (i = 0; i < len; i++) {
420 rc = next_entry(buf, fp, sizeof(u32) * 2); 415 rc = next_entry(buf, fp, sizeof(u32) * 2);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 9c5cdc2caaef..bc2a586f095c 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -1080,6 +1080,26 @@ out:
1080 * binary representation file. 1080 * binary representation file.
1081 */ 1081 */
1082 1082
1083static int str_read(char **strp, gfp_t flags, void *fp, u32 len)
1084{
1085 int rc;
1086 char *str;
1087
1088 str = kmalloc(len + 1, flags);
1089 if (!str)
1090 return -ENOMEM;
1091
1092 /* it's expected the caller should free the str */
1093 *strp = str;
1094
1095 rc = next_entry(str, fp, len);
1096 if (rc)
1097 return rc;
1098
1099 str[len] = '\0';
1100 return 0;
1101}
1102
1083static int perm_read(struct policydb *p, struct hashtab *h, void *fp) 1103static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
1084{ 1104{
1085 char *key = NULL; 1105 char *key = NULL;
@@ -1100,15 +1120,9 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
1100 len = le32_to_cpu(buf[0]); 1120 len = le32_to_cpu(buf[0]);
1101 perdatum->value = le32_to_cpu(buf[1]); 1121 perdatum->value = le32_to_cpu(buf[1]);
1102 1122
1103 rc = -ENOMEM; 1123 rc = str_read(&key, GFP_KERNEL, fp, len);
1104 key = kmalloc(len + 1, GFP_KERNEL);
1105 if (!key)
1106 goto bad;
1107
1108 rc = next_entry(key, fp, len);
1109 if (rc) 1124 if (rc)
1110 goto bad; 1125 goto bad;
1111 key[len] = '\0';
1112 1126
1113 rc = hashtab_insert(h, key, perdatum); 1127 rc = hashtab_insert(h, key, perdatum);
1114 if (rc) 1128 if (rc)
@@ -1146,15 +1160,9 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1146 comdatum->permissions.nprim = le32_to_cpu(buf[2]); 1160 comdatum->permissions.nprim = le32_to_cpu(buf[2]);
1147 nel = le32_to_cpu(buf[3]); 1161 nel = le32_to_cpu(buf[3]);
1148 1162
1149 rc = -ENOMEM; 1163 rc = str_read(&key, GFP_KERNEL, fp, len);
1150 key = kmalloc(len + 1, GFP_KERNEL);
1151 if (!key)
1152 goto bad;
1153
1154 rc = next_entry(key, fp, len);
1155 if (rc) 1164 if (rc)
1156 goto bad; 1165 goto bad;
1157 key[len] = '\0';
1158 1166
1159 for (i = 0; i < nel; i++) { 1167 for (i = 0; i < nel; i++) {
1160 rc = perm_read(p, comdatum->permissions.table, fp); 1168 rc = perm_read(p, comdatum->permissions.table, fp);
@@ -1321,25 +1329,14 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1321 1329
1322 ncons = le32_to_cpu(buf[5]); 1330 ncons = le32_to_cpu(buf[5]);
1323 1331
1324 rc = -ENOMEM; 1332 rc = str_read(&key, GFP_KERNEL, fp, len);
1325 key = kmalloc(len + 1, GFP_KERNEL);
1326 if (!key)
1327 goto bad;
1328
1329 rc = next_entry(key, fp, len);
1330 if (rc) 1333 if (rc)
1331 goto bad; 1334 goto bad;
1332 key[len] = '\0';
1333 1335
1334 if (len2) { 1336 if (len2) {
1335 rc = -ENOMEM; 1337 rc = str_read(&cladatum->comkey, GFP_KERNEL, fp, len2);
1336 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL);
1337 if (!cladatum->comkey)
1338 goto bad;
1339 rc = next_entry(cladatum->comkey, fp, len2);
1340 if (rc) 1338 if (rc)
1341 goto bad; 1339 goto bad;
1342 cladatum->comkey[len2] = '\0';
1343 1340
1344 rc = -EINVAL; 1341 rc = -EINVAL;
1345 cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey); 1342 cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey);
@@ -1422,15 +1419,9 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1422 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1419 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1423 role->bounds = le32_to_cpu(buf[2]); 1420 role->bounds = le32_to_cpu(buf[2]);
1424 1421
1425 rc = -ENOMEM; 1422 rc = str_read(&key, GFP_KERNEL, fp, len);
1426 key = kmalloc(len + 1, GFP_KERNEL);
1427 if (!key)
1428 goto bad;
1429
1430 rc = next_entry(key, fp, len);
1431 if (rc) 1423 if (rc)
1432 goto bad; 1424 goto bad;
1433 key[len] = '\0';
1434 1425
1435 rc = ebitmap_read(&role->dominates, fp); 1426 rc = ebitmap_read(&role->dominates, fp);
1436 if (rc) 1427 if (rc)
@@ -1495,14 +1486,9 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1495 typdatum->primary = le32_to_cpu(buf[2]); 1486 typdatum->primary = le32_to_cpu(buf[2]);
1496 } 1487 }
1497 1488
1498 rc = -ENOMEM; 1489 rc = str_read(&key, GFP_KERNEL, fp, len);
1499 key = kmalloc(len + 1, GFP_KERNEL);
1500 if (!key)
1501 goto bad;
1502 rc = next_entry(key, fp, len);
1503 if (rc) 1490 if (rc)
1504 goto bad; 1491 goto bad;
1505 key[len] = '\0';
1506 1492
1507 rc = hashtab_insert(h, key, typdatum); 1493 rc = hashtab_insert(h, key, typdatum);
1508 if (rc) 1494 if (rc)
@@ -1565,14 +1551,9 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1565 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1551 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1566 usrdatum->bounds = le32_to_cpu(buf[2]); 1552 usrdatum->bounds = le32_to_cpu(buf[2]);
1567 1553
1568 rc = -ENOMEM; 1554 rc = str_read(&key, GFP_KERNEL, fp, len);
1569 key = kmalloc(len + 1, GFP_KERNEL);
1570 if (!key)
1571 goto bad;
1572 rc = next_entry(key, fp, len);
1573 if (rc) 1555 if (rc)
1574 goto bad; 1556 goto bad;
1575 key[len] = '\0';
1576 1557
1577 rc = ebitmap_read(&usrdatum->roles, fp); 1558 rc = ebitmap_read(&usrdatum->roles, fp);
1578 if (rc) 1559 if (rc)
@@ -1616,14 +1597,9 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
1616 len = le32_to_cpu(buf[0]); 1597 len = le32_to_cpu(buf[0]);
1617 levdatum->isalias = le32_to_cpu(buf[1]); 1598 levdatum->isalias = le32_to_cpu(buf[1]);
1618 1599
1619 rc = -ENOMEM; 1600 rc = str_read(&key, GFP_ATOMIC, fp, len);
1620 key = kmalloc(len + 1, GFP_ATOMIC);
1621 if (!key)
1622 goto bad;
1623 rc = next_entry(key, fp, len);
1624 if (rc) 1601 if (rc)
1625 goto bad; 1602 goto bad;
1626 key[len] = '\0';
1627 1603
1628 rc = -ENOMEM; 1604 rc = -ENOMEM;
1629 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); 1605 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
@@ -1664,14 +1640,9 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
1664 catdatum->value = le32_to_cpu(buf[1]); 1640 catdatum->value = le32_to_cpu(buf[1]);
1665 catdatum->isalias = le32_to_cpu(buf[2]); 1641 catdatum->isalias = le32_to_cpu(buf[2]);
1666 1642
1667 rc = -ENOMEM; 1643 rc = str_read(&key, GFP_ATOMIC, fp, len);
1668 key = kmalloc(len + 1, GFP_ATOMIC);
1669 if (!key)
1670 goto bad;
1671 rc = next_entry(key, fp, len);
1672 if (rc) 1644 if (rc)
1673 goto bad; 1645 goto bad;
1674 key[len] = '\0';
1675 1646
1676 rc = hashtab_insert(h, key, catdatum); 1647 rc = hashtab_insert(h, key, catdatum);
1677 if (rc) 1648 if (rc)
@@ -1968,18 +1939,12 @@ static int filename_trans_read(struct policydb *p, void *fp)
1968 goto out; 1939 goto out;
1969 len = le32_to_cpu(buf[0]); 1940 len = le32_to_cpu(buf[0]);
1970 1941
1971 rc = -ENOMEM;
1972 name = kmalloc(len + 1, GFP_KERNEL);
1973 if (!name)
1974 goto out;
1975
1976 ft->name = name;
1977
1978 /* path component string */ 1942 /* path component string */
1979 rc = next_entry(name, fp, len); 1943 rc = str_read(&name, GFP_KERNEL, fp, len);
1980 if (rc) 1944 if (rc)
1981 goto out; 1945 goto out;
1982 name[len] = 0; 1946
1947 ft->name = name;
1983 1948
1984 rc = next_entry(buf, fp, sizeof(u32) * 4); 1949 rc = next_entry(buf, fp, sizeof(u32) * 4);
1985 if (rc) 1950 if (rc)
@@ -2045,17 +2010,10 @@ static int genfs_read(struct policydb *p, void *fp)
2045 if (!newgenfs) 2010 if (!newgenfs)
2046 goto out; 2011 goto out;
2047 2012
2048 rc = -ENOMEM; 2013 rc = str_read(&newgenfs->fstype, GFP_KERNEL, fp, len);
2049 newgenfs->fstype = kmalloc(len + 1, GFP_KERNEL);
2050 if (!newgenfs->fstype)
2051 goto out;
2052
2053 rc = next_entry(newgenfs->fstype, fp, len);
2054 if (rc) 2014 if (rc)
2055 goto out; 2015 goto out;
2056 2016
2057 newgenfs->fstype[len] = 0;
2058
2059 for (genfs_p = NULL, genfs = p->genfs; genfs; 2017 for (genfs_p = NULL, genfs = p->genfs; genfs;
2060 genfs_p = genfs, genfs = genfs->next) { 2018 genfs_p = genfs, genfs = genfs->next) {
2061 rc = -EINVAL; 2019 rc = -EINVAL;
@@ -2091,15 +2049,9 @@ static int genfs_read(struct policydb *p, void *fp)
2091 if (!newc) 2049 if (!newc)
2092 goto out; 2050 goto out;
2093 2051
2094 rc = -ENOMEM; 2052 rc = str_read(&newc->u.name, GFP_KERNEL, fp, len);
2095 newc->u.name = kmalloc(len + 1, GFP_KERNEL);
2096 if (!newc->u.name)
2097 goto out;
2098
2099 rc = next_entry(newc->u.name, fp, len);
2100 if (rc) 2053 if (rc)
2101 goto out; 2054 goto out;
2102 newc->u.name[len] = 0;
2103 2055
2104 rc = next_entry(buf, fp, sizeof(u32)); 2056 rc = next_entry(buf, fp, sizeof(u32));
2105 if (rc) 2057 if (rc)
@@ -2189,16 +2141,10 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2189 goto out; 2141 goto out;
2190 len = le32_to_cpu(buf[0]); 2142 len = le32_to_cpu(buf[0]);
2191 2143
2192 rc = -ENOMEM; 2144 rc = str_read(&c->u.name, GFP_KERNEL, fp, len);
2193 c->u.name = kmalloc(len + 1, GFP_KERNEL);
2194 if (!c->u.name)
2195 goto out;
2196
2197 rc = next_entry(c->u.name, fp, len);
2198 if (rc) 2145 if (rc)
2199 goto out; 2146 goto out;
2200 2147
2201 c->u.name[len] = 0;
2202 rc = context_read_and_validate(&c->context[0], p, fp); 2148 rc = context_read_and_validate(&c->context[0], p, fp);
2203 if (rc) 2149 if (rc)
2204 goto out; 2150 goto out;
@@ -2240,16 +2186,11 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2240 if (c->v.behavior > SECURITY_FS_USE_MAX) 2186 if (c->v.behavior > SECURITY_FS_USE_MAX)
2241 goto out; 2187 goto out;
2242 2188
2243 rc = -ENOMEM;
2244 len = le32_to_cpu(buf[1]); 2189 len = le32_to_cpu(buf[1]);
2245 c->u.name = kmalloc(len + 1, GFP_KERNEL); 2190 rc = str_read(&c->u.name, GFP_KERNEL, fp, len);
2246 if (!c->u.name)
2247 goto out;
2248
2249 rc = next_entry(c->u.name, fp, len);
2250 if (rc) 2191 if (rc)
2251 goto out; 2192 goto out;
2252 c->u.name[len] = 0; 2193
2253 rc = context_read_and_validate(&c->context[0], p, fp); 2194 rc = context_read_and_validate(&c->context[0], p, fp);
2254 if (rc) 2195 if (rc)
2255 goto out; 2196 goto out;
@@ -2608,7 +2549,7 @@ static int mls_write_range_helper(struct mls_range *r, void *fp)
2608 if (!eq) 2549 if (!eq)
2609 buf[2] = cpu_to_le32(r->level[1].sens); 2550 buf[2] = cpu_to_le32(r->level[1].sens);
2610 2551
2611 BUG_ON(items > (sizeof(buf)/sizeof(buf[0]))); 2552 BUG_ON(items > ARRAY_SIZE(buf));
2612 2553
2613 rc = put_entry(buf, sizeof(u32), items, fp); 2554 rc = put_entry(buf, sizeof(u32), items, fp);
2614 if (rc) 2555 if (rc)
@@ -2990,7 +2931,7 @@ static int role_write(void *vkey, void *datum, void *ptr)
2990 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 2931 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
2991 buf[items++] = cpu_to_le32(role->bounds); 2932 buf[items++] = cpu_to_le32(role->bounds);
2992 2933
2993 BUG_ON(items > (sizeof(buf)/sizeof(buf[0]))); 2934 BUG_ON(items > ARRAY_SIZE(buf));
2994 2935
2995 rc = put_entry(buf, sizeof(u32), items, fp); 2936 rc = put_entry(buf, sizeof(u32), items, fp);
2996 if (rc) 2937 if (rc)
@@ -3040,7 +2981,7 @@ static int type_write(void *vkey, void *datum, void *ptr)
3040 } else { 2981 } else {
3041 buf[items++] = cpu_to_le32(typdatum->primary); 2982 buf[items++] = cpu_to_le32(typdatum->primary);
3042 } 2983 }
3043 BUG_ON(items > (sizeof(buf) / sizeof(buf[0]))); 2984 BUG_ON(items > ARRAY_SIZE(buf));
3044 rc = put_entry(buf, sizeof(u32), items, fp); 2985 rc = put_entry(buf, sizeof(u32), items, fp);
3045 if (rc) 2986 if (rc)
3046 return rc; 2987 return rc;
@@ -3069,7 +3010,7 @@ static int user_write(void *vkey, void *datum, void *ptr)
3069 buf[items++] = cpu_to_le32(usrdatum->value); 3010 buf[items++] = cpu_to_le32(usrdatum->value);
3070 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 3011 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
3071 buf[items++] = cpu_to_le32(usrdatum->bounds); 3012 buf[items++] = cpu_to_le32(usrdatum->bounds);
3072 BUG_ON(items > (sizeof(buf) / sizeof(buf[0]))); 3013 BUG_ON(items > ARRAY_SIZE(buf));
3073 rc = put_entry(buf, sizeof(u32), items, fp); 3014 rc = put_entry(buf, sizeof(u32), items, fp);
3074 if (rc) 3015 if (rc)
3075 return rc; 3016 return rc;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 4bca49414a40..2aa9d172dc7e 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2277,7 +2277,7 @@ out:
2277} 2277}
2278 2278
2279/** 2279/**
2280 * security_genfs_sid - Obtain a SID for a file in a filesystem 2280 * __security_genfs_sid - Helper to obtain a SID for a file in a filesystem
2281 * @fstype: filesystem type 2281 * @fstype: filesystem type
2282 * @path: path from root of mount 2282 * @path: path from root of mount
2283 * @sclass: file security class 2283 * @sclass: file security class
@@ -2286,11 +2286,13 @@ out:
2286 * Obtain a SID to use for a file in a filesystem that 2286 * Obtain a SID to use for a file in a filesystem that
2287 * cannot support xattr or use a fixed labeling behavior like 2287 * cannot support xattr or use a fixed labeling behavior like
2288 * transition SIDs or task SIDs. 2288 * transition SIDs or task SIDs.
2289 *
2290 * The caller must acquire the policy_rwlock before calling this function.
2289 */ 2291 */
2290int security_genfs_sid(const char *fstype, 2292static inline int __security_genfs_sid(const char *fstype,
2291 char *path, 2293 char *path,
2292 u16 orig_sclass, 2294 u16 orig_sclass,
2293 u32 *sid) 2295 u32 *sid)
2294{ 2296{
2295 int len; 2297 int len;
2296 u16 sclass; 2298 u16 sclass;
@@ -2301,8 +2303,6 @@ int security_genfs_sid(const char *fstype,
2301 while (path[0] == '/' && path[1] == '/') 2303 while (path[0] == '/' && path[1] == '/')
2302 path++; 2304 path++;
2303 2305
2304 read_lock(&policy_rwlock);
2305
2306 sclass = unmap_class(orig_sclass); 2306 sclass = unmap_class(orig_sclass);
2307 *sid = SECINITSID_UNLABELED; 2307 *sid = SECINITSID_UNLABELED;
2308 2308
@@ -2336,11 +2336,33 @@ int security_genfs_sid(const char *fstype,
2336 *sid = c->sid[0]; 2336 *sid = c->sid[0];
2337 rc = 0; 2337 rc = 0;
2338out: 2338out:
2339 read_unlock(&policy_rwlock);
2340 return rc; 2339 return rc;
2341} 2340}
2342 2341
2343/** 2342/**
2343 * security_genfs_sid - Obtain a SID for a file in a filesystem
2344 * @fstype: filesystem type
2345 * @path: path from root of mount
2346 * @sclass: file security class
2347 * @sid: SID for path
2348 *
2349 * Acquire policy_rwlock before calling __security_genfs_sid() and release
2350 * it afterward.
2351 */
2352int security_genfs_sid(const char *fstype,
2353 char *path,
2354 u16 orig_sclass,
2355 u32 *sid)
2356{
2357 int retval;
2358
2359 read_lock(&policy_rwlock);
2360 retval = __security_genfs_sid(fstype, path, orig_sclass, sid);
2361 read_unlock(&policy_rwlock);
2362 return retval;
2363}
2364
2365/**
2344 * security_fs_use - Determine how to handle labeling for a filesystem. 2366 * security_fs_use - Determine how to handle labeling for a filesystem.
2345 * @sb: superblock in question 2367 * @sb: superblock in question
2346 */ 2368 */
@@ -2370,7 +2392,8 @@ int security_fs_use(struct super_block *sb)
2370 } 2392 }
2371 sbsec->sid = c->sid[0]; 2393 sbsec->sid = c->sid[0];
2372 } else { 2394 } else {
2373 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid); 2395 rc = __security_genfs_sid(fstype, "/", SECCLASS_DIR,
2396 &sbsec->sid);
2374 if (rc) { 2397 if (rc) {
2375 sbsec->behavior = SECURITY_FS_USE_NONE; 2398 sbsec->behavior = SECURITY_FS_USE_NONE;
2376 rc = 0; 2399 rc = 0;