aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/avc.c4
-rw-r--r--security/selinux/hooks.c180
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/netlink.c6
-rw-r--r--security/selinux/nlmsgtab.c3
-rw-r--r--security/selinux/ss/avtab.c196
-rw-r--r--security/selinux/ss/avtab.h37
-rw-r--r--security/selinux/ss/conditional.c215
-rw-r--r--security/selinux/ss/ebitmap.c5
-rw-r--r--security/selinux/ss/ebitmap.h30
-rw-r--r--security/selinux/ss/mls.c42
-rw-r--r--security/selinux/ss/policydb.c107
-rw-r--r--security/selinux/ss/policydb.h3
-rw-r--r--security/selinux/ss/services.c76
14 files changed, 516 insertions, 391 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 2d088bb65ee8..12e4fb72bf0f 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -490,7 +490,7 @@ out:
490} 490}
491 491
492static inline void avc_print_ipv6_addr(struct audit_buffer *ab, 492static inline void avc_print_ipv6_addr(struct audit_buffer *ab,
493 struct in6_addr *addr, u16 port, 493 struct in6_addr *addr, __be16 port,
494 char *name1, char *name2) 494 char *name1, char *name2)
495{ 495{
496 if (!ipv6_addr_any(addr)) 496 if (!ipv6_addr_any(addr))
@@ -501,7 +501,7 @@ static inline void avc_print_ipv6_addr(struct audit_buffer *ab,
501} 501}
502 502
503static inline void avc_print_ipv4_addr(struct audit_buffer *ab, u32 addr, 503static inline void avc_print_ipv4_addr(struct audit_buffer *ab, u32 addr,
504 u16 port, char *name1, char *name2) 504 __be16 port, char *name1, char *name2)
505{ 505{
506 if (addr) 506 if (addr)
507 audit_log_format(ab, " %s=%d.%d.%d.%d", name1, NIPQUAD(addr)); 507 audit_log_format(ab, " %s=%d.%d.%d.%d", name1, NIPQUAD(addr));
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9f9463000683..6e4937fe062b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -659,7 +659,7 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
659 return SECCLASS_NETLINK_ROUTE_SOCKET; 659 return SECCLASS_NETLINK_ROUTE_SOCKET;
660 case NETLINK_FIREWALL: 660 case NETLINK_FIREWALL:
661 return SECCLASS_NETLINK_FIREWALL_SOCKET; 661 return SECCLASS_NETLINK_FIREWALL_SOCKET;
662 case NETLINK_TCPDIAG: 662 case NETLINK_INET_DIAG:
663 return SECCLASS_NETLINK_TCPDIAG_SOCKET; 663 return SECCLASS_NETLINK_TCPDIAG_SOCKET;
664 case NETLINK_NFLOG: 664 case NETLINK_NFLOG:
665 return SECCLASS_NETLINK_NFLOG_SOCKET; 665 return SECCLASS_NETLINK_NFLOG_SOCKET;
@@ -1265,85 +1265,6 @@ static int inode_security_set_sid(struct inode *inode, u32 sid)
1265 return 0; 1265 return 0;
1266} 1266}
1267 1267
1268/* Set the security attributes on a newly created file. */
1269static int post_create(struct inode *dir,
1270 struct dentry *dentry)
1271{
1272
1273 struct task_security_struct *tsec;
1274 struct inode *inode;
1275 struct inode_security_struct *dsec;
1276 struct superblock_security_struct *sbsec;
1277 u32 newsid;
1278 char *context;
1279 unsigned int len;
1280 int rc;
1281
1282 tsec = current->security;
1283 dsec = dir->i_security;
1284 sbsec = dir->i_sb->s_security;
1285
1286 inode = dentry->d_inode;
1287 if (!inode) {
1288 /* Some file system types (e.g. NFS) may not instantiate
1289 a dentry for all create operations (e.g. symlink),
1290 so we have to check to see if the inode is non-NULL. */
1291 printk(KERN_WARNING "post_create: no inode, dir (dev=%s, "
1292 "ino=%ld)\n", dir->i_sb->s_id, dir->i_ino);
1293 return 0;
1294 }
1295
1296 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
1297 newsid = tsec->create_sid;
1298 } else {
1299 rc = security_transition_sid(tsec->sid, dsec->sid,
1300 inode_mode_to_security_class(inode->i_mode),
1301 &newsid);
1302 if (rc) {
1303 printk(KERN_WARNING "post_create: "
1304 "security_transition_sid failed, rc=%d (dev=%s "
1305 "ino=%ld)\n",
1306 -rc, inode->i_sb->s_id, inode->i_ino);
1307 return rc;
1308 }
1309 }
1310
1311 rc = inode_security_set_sid(inode, newsid);
1312 if (rc) {
1313 printk(KERN_WARNING "post_create: inode_security_set_sid "
1314 "failed, rc=%d (dev=%s ino=%ld)\n",
1315 -rc, inode->i_sb->s_id, inode->i_ino);
1316 return rc;
1317 }
1318
1319 if (sbsec->behavior == SECURITY_FS_USE_XATTR &&
1320 inode->i_op->setxattr) {
1321 /* Use extended attributes. */
1322 rc = security_sid_to_context(newsid, &context, &len);
1323 if (rc) {
1324 printk(KERN_WARNING "post_create: sid_to_context "
1325 "failed, rc=%d (dev=%s ino=%ld)\n",
1326 -rc, inode->i_sb->s_id, inode->i_ino);
1327 return rc;
1328 }
1329 down(&inode->i_sem);
1330 rc = inode->i_op->setxattr(dentry,
1331 XATTR_NAME_SELINUX,
1332 context, len, 0);
1333 up(&inode->i_sem);
1334 kfree(context);
1335 if (rc < 0) {
1336 printk(KERN_WARNING "post_create: setxattr failed, "
1337 "rc=%d (dev=%s ino=%ld)\n",
1338 -rc, inode->i_sb->s_id, inode->i_ino);
1339 return rc;
1340 }
1341 }
1342
1343 return 0;
1344}
1345
1346
1347/* Hook functions begin here. */ 1268/* Hook functions begin here. */
1348 1269
1349static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) 1270static int selinux_ptrace(struct task_struct *parent, struct task_struct *child)
@@ -1673,6 +1594,7 @@ static inline void flush_unauthorized_files(struct files_struct * files)
1673 struct avc_audit_data ad; 1594 struct avc_audit_data ad;
1674 struct file *file, *devnull = NULL; 1595 struct file *file, *devnull = NULL;
1675 struct tty_struct *tty = current->signal->tty; 1596 struct tty_struct *tty = current->signal->tty;
1597 struct fdtable *fdt;
1676 long j = -1; 1598 long j = -1;
1677 1599
1678 if (tty) { 1600 if (tty) {
@@ -1706,9 +1628,10 @@ static inline void flush_unauthorized_files(struct files_struct * files)
1706 1628
1707 j++; 1629 j++;
1708 i = j * __NFDBITS; 1630 i = j * __NFDBITS;
1709 if (i >= files->max_fds || i >= files->max_fdset) 1631 fdt = files_fdtable(files);
1632 if (i >= fdt->max_fds || i >= fdt->max_fdset)
1710 break; 1633 break;
1711 set = files->open_fds->fds_bits[j]; 1634 set = fdt->open_fds->fds_bits[j];
1712 if (!set) 1635 if (!set)
1713 continue; 1636 continue;
1714 spin_unlock(&files->file_lock); 1637 spin_unlock(&files->file_lock);
@@ -1729,7 +1652,7 @@ static inline void flush_unauthorized_files(struct files_struct * files)
1729 continue; 1652 continue;
1730 } 1653 }
1731 if (devnull) { 1654 if (devnull) {
1732 atomic_inc(&devnull->f_count); 1655 rcuref_inc(&devnull->f_count);
1733 } else { 1656 } else {
1734 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR); 1657 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);
1735 if (!devnull) { 1658 if (!devnull) {
@@ -2018,14 +1941,64 @@ static void selinux_inode_free_security(struct inode *inode)
2018 inode_free_security(inode); 1941 inode_free_security(inode);
2019} 1942}
2020 1943
2021static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask) 1944static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
1945 char **name, void **value,
1946 size_t *len)
2022{ 1947{
2023 return may_create(dir, dentry, SECCLASS_FILE); 1948 struct task_security_struct *tsec;
1949 struct inode_security_struct *dsec;
1950 struct superblock_security_struct *sbsec;
1951 struct inode_security_struct *isec;
1952 u32 newsid, clen;
1953 int rc;
1954 char *namep = NULL, *context;
1955
1956 tsec = current->security;
1957 dsec = dir->i_security;
1958 sbsec = dir->i_sb->s_security;
1959 isec = inode->i_security;
1960
1961 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
1962 newsid = tsec->create_sid;
1963 } else {
1964 rc = security_transition_sid(tsec->sid, dsec->sid,
1965 inode_mode_to_security_class(inode->i_mode),
1966 &newsid);
1967 if (rc) {
1968 printk(KERN_WARNING "%s: "
1969 "security_transition_sid failed, rc=%d (dev=%s "
1970 "ino=%ld)\n",
1971 __FUNCTION__,
1972 -rc, inode->i_sb->s_id, inode->i_ino);
1973 return rc;
1974 }
1975 }
1976
1977 inode_security_set_sid(inode, newsid);
1978
1979 if (name) {
1980 namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
1981 if (!namep)
1982 return -ENOMEM;
1983 *name = namep;
1984 }
1985
1986 if (value && len) {
1987 rc = security_sid_to_context(newsid, &context, &clen);
1988 if (rc) {
1989 kfree(namep);
1990 return rc;
1991 }
1992 *value = context;
1993 *len = clen;
1994 }
1995
1996 return 0;
2024} 1997}
2025 1998
2026static void selinux_inode_post_create(struct inode *dir, struct dentry *dentry, int mask) 1999static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
2027{ 2000{
2028 post_create(dir, dentry); 2001 return may_create(dir, dentry, SECCLASS_FILE);
2029} 2002}
2030 2003
2031static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) 2004static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
@@ -2038,11 +2011,6 @@ static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, stru
2038 return may_link(dir, old_dentry, MAY_LINK); 2011 return may_link(dir, old_dentry, MAY_LINK);
2039} 2012}
2040 2013
2041static void selinux_inode_post_link(struct dentry *old_dentry, struct inode *inode, struct dentry *new_dentry)
2042{
2043 return;
2044}
2045
2046static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry) 2014static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
2047{ 2015{
2048 int rc; 2016 int rc;
@@ -2058,21 +2026,11 @@ static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const
2058 return may_create(dir, dentry, SECCLASS_LNK_FILE); 2026 return may_create(dir, dentry, SECCLASS_LNK_FILE);
2059} 2027}
2060 2028
2061static void selinux_inode_post_symlink(struct inode *dir, struct dentry *dentry, const char *name)
2062{
2063 post_create(dir, dentry);
2064}
2065
2066static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask) 2029static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask)
2067{ 2030{
2068 return may_create(dir, dentry, SECCLASS_DIR); 2031 return may_create(dir, dentry, SECCLASS_DIR);
2069} 2032}
2070 2033
2071static void selinux_inode_post_mkdir(struct inode *dir, struct dentry *dentry, int mask)
2072{
2073 post_create(dir, dentry);
2074}
2075
2076static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry) 2034static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
2077{ 2035{
2078 return may_link(dir, dentry, MAY_RMDIR); 2036 return may_link(dir, dentry, MAY_RMDIR);
@@ -2089,23 +2047,12 @@ static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mod
2089 return may_create(dir, dentry, inode_mode_to_security_class(mode)); 2047 return may_create(dir, dentry, inode_mode_to_security_class(mode));
2090} 2048}
2091 2049
2092static void selinux_inode_post_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
2093{
2094 post_create(dir, dentry);
2095}
2096
2097static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry, 2050static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
2098 struct inode *new_inode, struct dentry *new_dentry) 2051 struct inode *new_inode, struct dentry *new_dentry)
2099{ 2052{
2100 return may_rename(old_inode, old_dentry, new_inode, new_dentry); 2053 return may_rename(old_inode, old_dentry, new_inode, new_dentry);
2101} 2054}
2102 2055
2103static void selinux_inode_post_rename(struct inode *old_inode, struct dentry *old_dentry,
2104 struct inode *new_inode, struct dentry *new_dentry)
2105{
2106 return;
2107}
2108
2109static int selinux_inode_readlink(struct dentry *dentry) 2056static int selinux_inode_readlink(struct dentry *dentry)
2110{ 2057{
2111 return dentry_has_perm(current, NULL, dentry, FILE__READ); 2058 return dentry_has_perm(current, NULL, dentry, FILE__READ);
@@ -4298,20 +4245,15 @@ static struct security_operations selinux_ops = {
4298 4245
4299 .inode_alloc_security = selinux_inode_alloc_security, 4246 .inode_alloc_security = selinux_inode_alloc_security,
4300 .inode_free_security = selinux_inode_free_security, 4247 .inode_free_security = selinux_inode_free_security,
4248 .inode_init_security = selinux_inode_init_security,
4301 .inode_create = selinux_inode_create, 4249 .inode_create = selinux_inode_create,
4302 .inode_post_create = selinux_inode_post_create,
4303 .inode_link = selinux_inode_link, 4250 .inode_link = selinux_inode_link,
4304 .inode_post_link = selinux_inode_post_link,
4305 .inode_unlink = selinux_inode_unlink, 4251 .inode_unlink = selinux_inode_unlink,
4306 .inode_symlink = selinux_inode_symlink, 4252 .inode_symlink = selinux_inode_symlink,
4307 .inode_post_symlink = selinux_inode_post_symlink,
4308 .inode_mkdir = selinux_inode_mkdir, 4253 .inode_mkdir = selinux_inode_mkdir,
4309 .inode_post_mkdir = selinux_inode_post_mkdir,
4310 .inode_rmdir = selinux_inode_rmdir, 4254 .inode_rmdir = selinux_inode_rmdir,
4311 .inode_mknod = selinux_inode_mknod, 4255 .inode_mknod = selinux_inode_mknod,
4312 .inode_post_mknod = selinux_inode_post_mknod,
4313 .inode_rename = selinux_inode_rename, 4256 .inode_rename = selinux_inode_rename,
4314 .inode_post_rename = selinux_inode_post_rename,
4315 .inode_readlink = selinux_inode_readlink, 4257 .inode_readlink = selinux_inode_readlink,
4316 .inode_follow_link = selinux_inode_follow_link, 4258 .inode_follow_link = selinux_inode_follow_link,
4317 .inode_permission = selinux_inode_permission, 4259 .inode_permission = selinux_inode_permission,
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 71c0a19c9753..5f016c98056f 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -23,10 +23,11 @@
23#define POLICYDB_VERSION_NLCLASS 18 23#define POLICYDB_VERSION_NLCLASS 18
24#define POLICYDB_VERSION_VALIDATETRANS 19 24#define POLICYDB_VERSION_VALIDATETRANS 19
25#define POLICYDB_VERSION_MLS 19 25#define POLICYDB_VERSION_MLS 19
26#define POLICYDB_VERSION_AVTAB 20
26 27
27/* Range of policy versions we understand*/ 28/* Range of policy versions we understand*/
28#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 29#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
29#define POLICYDB_VERSION_MAX POLICYDB_VERSION_MLS 30#define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB
30 31
31#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM 32#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
32extern int selinux_enabled; 33extern int selinux_enabled;
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c
index 18d08acafa78..e203883406dd 100644
--- a/security/selinux/netlink.c
+++ b/security/selinux/netlink.c
@@ -80,7 +80,8 @@ static void selnl_notify(int msgtype, void *data)
80 nlh = NLMSG_PUT(skb, 0, 0, msgtype, len); 80 nlh = NLMSG_PUT(skb, 0, 0, msgtype, len);
81 selnl_add_payload(nlh, len, msgtype, data); 81 selnl_add_payload(nlh, len, msgtype, data);
82 nlh->nlmsg_len = skb->tail - tmp; 82 nlh->nlmsg_len = skb->tail - tmp;
83 netlink_broadcast(selnl, skb, 0, SELNL_GRP_AVC, GFP_USER); 83 NETLINK_CB(skb).dst_group = SELNLGRP_AVC;
84 netlink_broadcast(selnl, skb, 0, SELNLGRP_AVC, GFP_USER);
84out: 85out:
85 return; 86 return;
86 87
@@ -103,7 +104,8 @@ void selnl_notify_policyload(u32 seqno)
103 104
104static int __init selnl_init(void) 105static int __init selnl_init(void)
105{ 106{
106 selnl = netlink_kernel_create(NETLINK_SELINUX, NULL); 107 selnl = netlink_kernel_create(NETLINK_SELINUX, SELNLGRP_MAX, NULL,
108 THIS_MODULE);
107 if (selnl == NULL) 109 if (selnl == NULL)
108 panic("SELinux: Cannot create netlink socket."); 110 panic("SELinux: Cannot create netlink socket.");
109 netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV); 111 netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV);
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 92b057becb4b..69b9329b2054 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -16,7 +16,7 @@
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <linux/if.h> 17#include <linux/if.h>
18#include <linux/netfilter_ipv4/ip_queue.h> 18#include <linux/netfilter_ipv4/ip_queue.h>
19#include <linux/tcp_diag.h> 19#include <linux/inet_diag.h>
20#include <linux/xfrm.h> 20#include <linux/xfrm.h>
21#include <linux/audit.h> 21#include <linux/audit.h>
22 22
@@ -76,6 +76,7 @@ static struct nlmsg_perm nlmsg_firewall_perms[] =
76static struct nlmsg_perm nlmsg_tcpdiag_perms[] = 76static struct nlmsg_perm nlmsg_tcpdiag_perms[] =
77{ 77{
78 { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, 78 { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ },
79 { DCCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ },
79}; 80};
80 81
81static struct nlmsg_perm nlmsg_xfrm_perms[] = 82static struct nlmsg_perm nlmsg_xfrm_perms[] =
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index f238c034c44e..dde094feb20d 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -58,6 +58,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
58{ 58{
59 int hvalue; 59 int hvalue;
60 struct avtab_node *prev, *cur, *newnode; 60 struct avtab_node *prev, *cur, *newnode;
61 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
61 62
62 if (!h) 63 if (!h)
63 return -EINVAL; 64 return -EINVAL;
@@ -69,7 +70,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
69 if (key->source_type == cur->key.source_type && 70 if (key->source_type == cur->key.source_type &&
70 key->target_type == cur->key.target_type && 71 key->target_type == cur->key.target_type &&
71 key->target_class == cur->key.target_class && 72 key->target_class == cur->key.target_class &&
72 (datum->specified & cur->datum.specified)) 73 (specified & cur->key.specified))
73 return -EEXIST; 74 return -EEXIST;
74 if (key->source_type < cur->key.source_type) 75 if (key->source_type < cur->key.source_type)
75 break; 76 break;
@@ -98,6 +99,7 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
98{ 99{
99 int hvalue; 100 int hvalue;
100 struct avtab_node *prev, *cur, *newnode; 101 struct avtab_node *prev, *cur, *newnode;
102 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
101 103
102 if (!h) 104 if (!h)
103 return NULL; 105 return NULL;
@@ -108,7 +110,7 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
108 if (key->source_type == cur->key.source_type && 110 if (key->source_type == cur->key.source_type &&
109 key->target_type == cur->key.target_type && 111 key->target_type == cur->key.target_type &&
110 key->target_class == cur->key.target_class && 112 key->target_class == cur->key.target_class &&
111 (datum->specified & cur->datum.specified)) 113 (specified & cur->key.specified))
112 break; 114 break;
113 if (key->source_type < cur->key.source_type) 115 if (key->source_type < cur->key.source_type)
114 break; 116 break;
@@ -125,10 +127,11 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
125 return newnode; 127 return newnode;
126} 128}
127 129
128struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int specified) 130struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
129{ 131{
130 int hvalue; 132 int hvalue;
131 struct avtab_node *cur; 133 struct avtab_node *cur;
134 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
132 135
133 if (!h) 136 if (!h)
134 return NULL; 137 return NULL;
@@ -138,7 +141,7 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int spe
138 if (key->source_type == cur->key.source_type && 141 if (key->source_type == cur->key.source_type &&
139 key->target_type == cur->key.target_type && 142 key->target_type == cur->key.target_type &&
140 key->target_class == cur->key.target_class && 143 key->target_class == cur->key.target_class &&
141 (specified & cur->datum.specified)) 144 (specified & cur->key.specified))
142 return &cur->datum; 145 return &cur->datum;
143 146
144 if (key->source_type < cur->key.source_type) 147 if (key->source_type < cur->key.source_type)
@@ -159,10 +162,11 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int spe
159 * conjunction with avtab_search_next_node() 162 * conjunction with avtab_search_next_node()
160 */ 163 */
161struct avtab_node* 164struct avtab_node*
162avtab_search_node(struct avtab *h, struct avtab_key *key, int specified) 165avtab_search_node(struct avtab *h, struct avtab_key *key)
163{ 166{
164 int hvalue; 167 int hvalue;
165 struct avtab_node *cur; 168 struct avtab_node *cur;
169 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
166 170
167 if (!h) 171 if (!h)
168 return NULL; 172 return NULL;
@@ -172,7 +176,7 @@ avtab_search_node(struct avtab *h, struct avtab_key *key, int specified)
172 if (key->source_type == cur->key.source_type && 176 if (key->source_type == cur->key.source_type &&
173 key->target_type == cur->key.target_type && 177 key->target_type == cur->key.target_type &&
174 key->target_class == cur->key.target_class && 178 key->target_class == cur->key.target_class &&
175 (specified & cur->datum.specified)) 179 (specified & cur->key.specified))
176 return cur; 180 return cur;
177 181
178 if (key->source_type < cur->key.source_type) 182 if (key->source_type < cur->key.source_type)
@@ -196,11 +200,12 @@ avtab_search_node_next(struct avtab_node *node, int specified)
196 if (!node) 200 if (!node)
197 return NULL; 201 return NULL;
198 202
203 specified &= ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
199 for (cur = node->next; cur; cur = cur->next) { 204 for (cur = node->next; cur; cur = cur->next) {
200 if (node->key.source_type == cur->key.source_type && 205 if (node->key.source_type == cur->key.source_type &&
201 node->key.target_type == cur->key.target_type && 206 node->key.target_type == cur->key.target_type &&
202 node->key.target_class == cur->key.target_class && 207 node->key.target_class == cur->key.target_class &&
203 (specified & cur->datum.specified)) 208 (specified & cur->key.specified))
204 return cur; 209 return cur;
205 210
206 if (node->key.source_type < cur->key.source_type) 211 if (node->key.source_type < cur->key.source_type)
@@ -278,76 +283,129 @@ void avtab_hash_eval(struct avtab *h, char *tag)
278 max_chain_len); 283 max_chain_len);
279} 284}
280 285
281int avtab_read_item(void *fp, struct avtab_datum *avdatum, struct avtab_key *avkey) 286static uint16_t spec_order[] = {
287 AVTAB_ALLOWED,
288 AVTAB_AUDITDENY,
289 AVTAB_AUDITALLOW,
290 AVTAB_TRANSITION,
291 AVTAB_CHANGE,
292 AVTAB_MEMBER
293};
294
295int avtab_read_item(void *fp, u32 vers, struct avtab *a,
296 int (*insertf)(struct avtab *a, struct avtab_key *k,
297 struct avtab_datum *d, void *p),
298 void *p)
282{ 299{
283 u32 buf[7]; 300 __le16 buf16[4];
284 u32 items, items2; 301 u16 enabled;
285 int rc; 302 __le32 buf32[7];
303 u32 items, items2, val;
304 struct avtab_key key;
305 struct avtab_datum datum;
306 int i, rc;
307
308 memset(&key, 0, sizeof(struct avtab_key));
309 memset(&datum, 0, sizeof(struct avtab_datum));
310
311 if (vers < POLICYDB_VERSION_AVTAB) {
312 rc = next_entry(buf32, fp, sizeof(u32));
313 if (rc < 0) {
314 printk(KERN_ERR "security: avtab: truncated entry\n");
315 return -1;
316 }
317 items2 = le32_to_cpu(buf32[0]);
318 if (items2 > ARRAY_SIZE(buf32)) {
319 printk(KERN_ERR "security: avtab: entry overflow\n");
320 return -1;
286 321
287 memset(avkey, 0, sizeof(struct avtab_key)); 322 }
288 memset(avdatum, 0, sizeof(struct avtab_datum)); 323 rc = next_entry(buf32, fp, sizeof(u32)*items2);
324 if (rc < 0) {
325 printk(KERN_ERR "security: avtab: truncated entry\n");
326 return -1;
327 }
328 items = 0;
289 329
290 rc = next_entry(buf, fp, sizeof(u32)); 330 val = le32_to_cpu(buf32[items++]);
291 if (rc < 0) { 331 key.source_type = (u16)val;
292 printk(KERN_ERR "security: avtab: truncated entry\n"); 332 if (key.source_type != val) {
293 goto bad; 333 printk("security: avtab: truncated source type\n");
294 } 334 return -1;
295 items2 = le32_to_cpu(buf[0]); 335 }
296 if (items2 > ARRAY_SIZE(buf)) { 336 val = le32_to_cpu(buf32[items++]);
297 printk(KERN_ERR "security: avtab: entry overflow\n"); 337 key.target_type = (u16)val;
298 goto bad; 338 if (key.target_type != val) {
339 printk("security: avtab: truncated target type\n");
340 return -1;
341 }
342 val = le32_to_cpu(buf32[items++]);
343 key.target_class = (u16)val;
344 if (key.target_class != val) {
345 printk("security: avtab: truncated target class\n");
346 return -1;
347 }
348
349 val = le32_to_cpu(buf32[items++]);
350 enabled = (val & AVTAB_ENABLED_OLD) ? AVTAB_ENABLED : 0;
351
352 if (!(val & (AVTAB_AV | AVTAB_TYPE))) {
353 printk("security: avtab: null entry\n");
354 return -1;
355 }
356 if ((val & AVTAB_AV) &&
357 (val & AVTAB_TYPE)) {
358 printk("security: avtab: entry has both access vectors and types\n");
359 return -1;
360 }
361
362 for (i = 0; i < sizeof(spec_order)/sizeof(u16); i++) {
363 if (val & spec_order[i]) {
364 key.specified = spec_order[i] | enabled;
365 datum.data = le32_to_cpu(buf32[items++]);
366 rc = insertf(a, &key, &datum, p);
367 if (rc) return rc;
368 }
369 }
370
371 if (items != items2) {
372 printk("security: avtab: entry only had %d items, expected %d\n", items2, items);
373 return -1;
374 }
375 return 0;
299 } 376 }
300 rc = next_entry(buf, fp, sizeof(u32)*items2); 377
378 rc = next_entry(buf16, fp, sizeof(u16)*4);
301 if (rc < 0) { 379 if (rc < 0) {
302 printk(KERN_ERR "security: avtab: truncated entry\n"); 380 printk("security: avtab: truncated entry\n");
303 goto bad; 381 return -1;
304 } 382 }
383
305 items = 0; 384 items = 0;
306 avkey->source_type = le32_to_cpu(buf[items++]); 385 key.source_type = le16_to_cpu(buf16[items++]);
307 avkey->target_type = le32_to_cpu(buf[items++]); 386 key.target_type = le16_to_cpu(buf16[items++]);
308 avkey->target_class = le32_to_cpu(buf[items++]); 387 key.target_class = le16_to_cpu(buf16[items++]);
309 avdatum->specified = le32_to_cpu(buf[items++]); 388 key.specified = le16_to_cpu(buf16[items++]);
310 if (!(avdatum->specified & (AVTAB_AV | AVTAB_TYPE))) { 389
311 printk(KERN_ERR "security: avtab: null entry\n"); 390 rc = next_entry(buf32, fp, sizeof(u32));
312 goto bad; 391 if (rc < 0) {
313 } 392 printk("security: avtab: truncated entry\n");
314 if ((avdatum->specified & AVTAB_AV) && 393 return -1;
315 (avdatum->specified & AVTAB_TYPE)) {
316 printk(KERN_ERR "security: avtab: entry has both access vectors and types\n");
317 goto bad;
318 }
319 if (avdatum->specified & AVTAB_AV) {
320 if (avdatum->specified & AVTAB_ALLOWED)
321 avtab_allowed(avdatum) = le32_to_cpu(buf[items++]);
322 if (avdatum->specified & AVTAB_AUDITDENY)
323 avtab_auditdeny(avdatum) = le32_to_cpu(buf[items++]);
324 if (avdatum->specified & AVTAB_AUDITALLOW)
325 avtab_auditallow(avdatum) = le32_to_cpu(buf[items++]);
326 } else {
327 if (avdatum->specified & AVTAB_TRANSITION)
328 avtab_transition(avdatum) = le32_to_cpu(buf[items++]);
329 if (avdatum->specified & AVTAB_CHANGE)
330 avtab_change(avdatum) = le32_to_cpu(buf[items++]);
331 if (avdatum->specified & AVTAB_MEMBER)
332 avtab_member(avdatum) = le32_to_cpu(buf[items++]);
333 }
334 if (items != items2) {
335 printk(KERN_ERR "security: avtab: entry only had %d items, expected %d\n",
336 items2, items);
337 goto bad;
338 } 394 }
395 datum.data = le32_to_cpu(*buf32);
396 return insertf(a, &key, &datum, p);
397}
339 398
340 return 0; 399static int avtab_insertf(struct avtab *a, struct avtab_key *k,
341bad: 400 struct avtab_datum *d, void *p)
342 return -1; 401{
402 return avtab_insert(a, k, d);
343} 403}
344 404
345int avtab_read(struct avtab *a, void *fp, u32 config) 405int avtab_read(struct avtab *a, void *fp, u32 vers)
346{ 406{
347 int rc; 407 int rc;
348 struct avtab_key avkey; 408 __le32 buf[1];
349 struct avtab_datum avdatum;
350 u32 buf[1];
351 u32 nel, i; 409 u32 nel, i;
352 410
353 411
@@ -363,16 +421,14 @@ int avtab_read(struct avtab *a, void *fp, u32 config)
363 goto bad; 421 goto bad;
364 } 422 }
365 for (i = 0; i < nel; i++) { 423 for (i = 0; i < nel; i++) {
366 if (avtab_read_item(fp, &avdatum, &avkey)) { 424 rc = avtab_read_item(fp,vers, a, avtab_insertf, NULL);
367 rc = -EINVAL;
368 goto bad;
369 }
370 rc = avtab_insert(a, &avkey, &avdatum);
371 if (rc) { 425 if (rc) {
372 if (rc == -ENOMEM) 426 if (rc == -ENOMEM)
373 printk(KERN_ERR "security: avtab: out of memory\n"); 427 printk(KERN_ERR "security: avtab: out of memory\n");
374 if (rc == -EEXIST) 428 else if (rc == -EEXIST)
375 printk(KERN_ERR "security: avtab: duplicate entry\n"); 429 printk(KERN_ERR "security: avtab: duplicate entry\n");
430 else
431 rc = -EINVAL;
376 goto bad; 432 goto bad;
377 } 433 }
378 } 434 }
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index 519d4f6dc655..0a90d939af93 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -21,12 +21,9 @@
21#define _SS_AVTAB_H_ 21#define _SS_AVTAB_H_
22 22
23struct avtab_key { 23struct avtab_key {
24 u32 source_type; /* source type */ 24 u16 source_type; /* source type */
25 u32 target_type; /* target type */ 25 u16 target_type; /* target type */
26 u32 target_class; /* target object class */ 26 u16 target_class; /* target object class */
27};
28
29struct avtab_datum {
30#define AVTAB_ALLOWED 1 27#define AVTAB_ALLOWED 1
31#define AVTAB_AUDITALLOW 2 28#define AVTAB_AUDITALLOW 2
32#define AVTAB_AUDITDENY 4 29#define AVTAB_AUDITDENY 4
@@ -35,15 +32,13 @@ struct avtab_datum {
35#define AVTAB_MEMBER 32 32#define AVTAB_MEMBER 32
36#define AVTAB_CHANGE 64 33#define AVTAB_CHANGE 64
37#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) 34#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)
38#define AVTAB_ENABLED 0x80000000 /* reserved for used in cond_avtab */ 35#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */
39 u32 specified; /* what fields are specified */ 36#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */
40 u32 data[3]; /* access vectors or types */ 37 u16 specified; /* what field is specified */
41#define avtab_allowed(x) (x)->data[0] 38};
42#define avtab_auditdeny(x) (x)->data[1] 39
43#define avtab_auditallow(x) (x)->data[2] 40struct avtab_datum {
44#define avtab_transition(x) (x)->data[0] 41 u32 data; /* access vector or type value */
45#define avtab_change(x) (x)->data[1]
46#define avtab_member(x) (x)->data[2]
47}; 42};
48 43
49struct avtab_node { 44struct avtab_node {
@@ -58,17 +53,21 @@ struct avtab {
58}; 53};
59 54
60int avtab_init(struct avtab *); 55int avtab_init(struct avtab *);
61struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k, int specified); 56struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k);
62void avtab_destroy(struct avtab *h); 57void avtab_destroy(struct avtab *h);
63void avtab_hash_eval(struct avtab *h, char *tag); 58void avtab_hash_eval(struct avtab *h, char *tag);
64 59
65int avtab_read_item(void *fp, struct avtab_datum *avdatum, struct avtab_key *avkey); 60int avtab_read_item(void *fp, uint32_t vers, struct avtab *a,
66int avtab_read(struct avtab *a, void *fp, u32 config); 61 int (*insert)(struct avtab *a, struct avtab_key *k,
62 struct avtab_datum *d, void *p),
63 void *p);
64
65int avtab_read(struct avtab *a, void *fp, u32 vers);
67 66
68struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, 67struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key,
69 struct avtab_datum *datum); 68 struct avtab_datum *datum);
70 69
71struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key, int specified); 70struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key);
72 71
73struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified); 72struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified);
74 73
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index e2057f5a411a..daf288007460 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -100,18 +100,18 @@ int evaluate_cond_node(struct policydb *p, struct cond_node *node)
100 /* turn the rules on or off */ 100 /* turn the rules on or off */
101 for (cur = node->true_list; cur != NULL; cur = cur->next) { 101 for (cur = node->true_list; cur != NULL; cur = cur->next) {
102 if (new_state <= 0) { 102 if (new_state <= 0) {
103 cur->node->datum.specified &= ~AVTAB_ENABLED; 103 cur->node->key.specified &= ~AVTAB_ENABLED;
104 } else { 104 } else {
105 cur->node->datum.specified |= AVTAB_ENABLED; 105 cur->node->key.specified |= AVTAB_ENABLED;
106 } 106 }
107 } 107 }
108 108
109 for (cur = node->false_list; cur != NULL; cur = cur->next) { 109 for (cur = node->false_list; cur != NULL; cur = cur->next) {
110 /* -1 or 1 */ 110 /* -1 or 1 */
111 if (new_state) { 111 if (new_state) {
112 cur->node->datum.specified &= ~AVTAB_ENABLED; 112 cur->node->key.specified &= ~AVTAB_ENABLED;
113 } else { 113 } else {
114 cur->node->datum.specified |= AVTAB_ENABLED; 114 cur->node->key.specified |= AVTAB_ENABLED;
115 } 115 }
116 } 116 }
117 } 117 }
@@ -216,7 +216,8 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
216{ 216{
217 char *key = NULL; 217 char *key = NULL;
218 struct cond_bool_datum *booldatum; 218 struct cond_bool_datum *booldatum;
219 u32 buf[3], len; 219 __le32 buf[3];
220 u32 len;
220 int rc; 221 int rc;
221 222
222 booldatum = kmalloc(sizeof(struct cond_bool_datum), GFP_KERNEL); 223 booldatum = kmalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
@@ -252,104 +253,127 @@ err:
252 return -1; 253 return -1;
253} 254}
254 255
255static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list **ret_list, 256struct cond_insertf_data
256 struct cond_av_list *other)
257{ 257{
258 struct cond_av_list *list, *last = NULL, *cur; 258 struct policydb *p;
259 struct avtab_key key; 259 struct cond_av_list *other;
260 struct avtab_datum datum; 260 struct cond_av_list *head;
261 struct cond_av_list *tail;
262};
263
264static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum *d, void *ptr)
265{
266 struct cond_insertf_data *data = ptr;
267 struct policydb *p = data->p;
268 struct cond_av_list *other = data->other, *list, *cur;
261 struct avtab_node *node_ptr; 269 struct avtab_node *node_ptr;
262 int rc;
263 u32 buf[1], i, len;
264 u8 found; 270 u8 found;
265 271
266 *ret_list = NULL;
267
268 len = 0;
269 rc = next_entry(buf, fp, sizeof buf);
270 if (rc < 0)
271 return -1;
272
273 len = le32_to_cpu(buf[0]);
274 if (len == 0) {
275 return 0;
276 }
277 272
278 for (i = 0; i < len; i++) { 273 /*
279 if (avtab_read_item(fp, &datum, &key)) 274 * For type rules we have to make certain there aren't any
275 * conflicting rules by searching the te_avtab and the
276 * cond_te_avtab.
277 */
278 if (k->specified & AVTAB_TYPE) {
279 if (avtab_search(&p->te_avtab, k)) {
280 printk("security: type rule already exists outside of a conditional.");
280 goto err; 281 goto err;
281 282 }
282 /* 283 /*
283 * For type rules we have to make certain there aren't any 284 * If we are reading the false list other will be a pointer to
284 * conflicting rules by searching the te_avtab and the 285 * the true list. We can have duplicate entries if there is only
285 * cond_te_avtab. 286 * 1 other entry and it is in our true list.
287 *
288 * If we are reading the true list (other == NULL) there shouldn't
289 * be any other entries.
286 */ 290 */
287 if (datum.specified & AVTAB_TYPE) { 291 if (other) {
288 if (avtab_search(&p->te_avtab, &key, AVTAB_TYPE)) { 292 node_ptr = avtab_search_node(&p->te_cond_avtab, k);
289 printk("security: type rule already exists outside of a conditional."); 293 if (node_ptr) {
290 goto err; 294 if (avtab_search_node_next(node_ptr, k->specified)) {
291 } 295 printk("security: too many conflicting type rules.");
292 /* 296 goto err;
293 * If we are reading the false list other will be a pointer to 297 }
294 * the true list. We can have duplicate entries if there is only 298 found = 0;
295 * 1 other entry and it is in our true list. 299 for (cur = other; cur != NULL; cur = cur->next) {
296 * 300 if (cur->node == node_ptr) {
297 * If we are reading the true list (other == NULL) there shouldn't 301 found = 1;
298 * be any other entries. 302 break;
299 */
300 if (other) {
301 node_ptr = avtab_search_node(&p->te_cond_avtab, &key, AVTAB_TYPE);
302 if (node_ptr) {
303 if (avtab_search_node_next(node_ptr, AVTAB_TYPE)) {
304 printk("security: too many conflicting type rules.");
305 goto err;
306 }
307 found = 0;
308 for (cur = other; cur != NULL; cur = cur->next) {
309 if (cur->node == node_ptr) {
310 found = 1;
311 break;
312 }
313 }
314 if (!found) {
315 printk("security: conflicting type rules.");
316 goto err;
317 } 303 }
318 } 304 }
319 } else { 305 if (!found) {
320 if (avtab_search(&p->te_cond_avtab, &key, AVTAB_TYPE)) { 306 printk("security: conflicting type rules.\n");
321 printk("security: conflicting type rules when adding type rule for true.");
322 goto err; 307 goto err;
323 } 308 }
324 } 309 }
310 } else {
311 if (avtab_search(&p->te_cond_avtab, k)) {
312 printk("security: conflicting type rules when adding type rule for true.\n");
313 goto err;
314 }
325 } 315 }
326 node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, &key, &datum); 316 }
327 if (!node_ptr) {
328 printk("security: could not insert rule.");
329 goto err;
330 }
331
332 list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL);
333 if (!list)
334 goto err;
335 memset(list, 0, sizeof(struct cond_av_list));
336
337 list->node = node_ptr;
338 if (i == 0)
339 *ret_list = list;
340 else
341 last->next = list;
342 last = list;
343 317
318 node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, k, d);
319 if (!node_ptr) {
320 printk("security: could not insert rule.");
321 goto err;
344 } 322 }
345 323
324 list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL);
325 if (!list)
326 goto err;
327 memset(list, 0, sizeof(*list));
328
329 list->node = node_ptr;
330 if (!data->head)
331 data->head = list;
332 else
333 data->tail->next = list;
334 data->tail = list;
346 return 0; 335 return 0;
336
347err: 337err:
348 cond_av_list_destroy(*ret_list); 338 cond_av_list_destroy(data->head);
349 *ret_list = NULL; 339 data->head = NULL;
350 return -1; 340 return -1;
351} 341}
352 342
343static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list **ret_list, struct cond_av_list *other)
344{
345 int i, rc;
346 __le32 buf[1];
347 u32 len;
348 struct cond_insertf_data data;
349
350 *ret_list = NULL;
351
352 len = 0;
353 rc = next_entry(buf, fp, sizeof(u32));
354 if (rc < 0)
355 return -1;
356
357 len = le32_to_cpu(buf[0]);
358 if (len == 0) {
359 return 0;
360 }
361
362 data.p = p;
363 data.other = other;
364 data.head = NULL;
365 data.tail = NULL;
366 for (i = 0; i < len; i++) {
367 rc = avtab_read_item(fp, p->policyvers, &p->te_cond_avtab, cond_insertf, &data);
368 if (rc)
369 return rc;
370
371 }
372
373 *ret_list = data.head;
374 return 0;
375}
376
353static int expr_isvalid(struct policydb *p, struct cond_expr *expr) 377static int expr_isvalid(struct policydb *p, struct cond_expr *expr)
354{ 378{
355 if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) { 379 if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) {
@@ -366,7 +390,8 @@ static int expr_isvalid(struct policydb *p, struct cond_expr *expr)
366 390
367static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) 391static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
368{ 392{
369 u32 buf[2], len, i; 393 __le32 buf[2];
394 u32 len, i;
370 int rc; 395 int rc;
371 struct cond_expr *expr = NULL, *last = NULL; 396 struct cond_expr *expr = NULL, *last = NULL;
372 397
@@ -424,7 +449,8 @@ err:
424int cond_read_list(struct policydb *p, void *fp) 449int cond_read_list(struct policydb *p, void *fp)
425{ 450{
426 struct cond_node *node, *last = NULL; 451 struct cond_node *node, *last = NULL;
427 u32 buf[1], i, len; 452 __le32 buf[1];
453 u32 i, len;
428 int rc; 454 int rc;
429 455
430 rc = next_entry(buf, fp, sizeof buf); 456 rc = next_entry(buf, fp, sizeof buf);
@@ -452,6 +478,7 @@ int cond_read_list(struct policydb *p, void *fp)
452 return 0; 478 return 0;
453err: 479err:
454 cond_list_destroy(p->cond_list); 480 cond_list_destroy(p->cond_list);
481 p->cond_list = NULL;
455 return -1; 482 return -1;
456} 483}
457 484
@@ -465,22 +492,22 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decisi
465 if(!ctab || !key || !avd) 492 if(!ctab || !key || !avd)
466 return; 493 return;
467 494
468 for(node = avtab_search_node(ctab, key, AVTAB_AV); node != NULL; 495 for(node = avtab_search_node(ctab, key); node != NULL;
469 node = avtab_search_node_next(node, AVTAB_AV)) { 496 node = avtab_search_node_next(node, key->specified)) {
470 if ( (__u32) (AVTAB_ALLOWED|AVTAB_ENABLED) == 497 if ( (u16) (AVTAB_ALLOWED|AVTAB_ENABLED) ==
471 (node->datum.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) 498 (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED)))
472 avd->allowed |= avtab_allowed(&node->datum); 499 avd->allowed |= node->datum.data;
473 if ( (__u32) (AVTAB_AUDITDENY|AVTAB_ENABLED) == 500 if ( (u16) (AVTAB_AUDITDENY|AVTAB_ENABLED) ==
474 (node->datum.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED))) 501 (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED)))
475 /* Since a '0' in an auditdeny mask represents a 502 /* Since a '0' in an auditdeny mask represents a
476 * permission we do NOT want to audit (dontaudit), we use 503 * permission we do NOT want to audit (dontaudit), we use
477 * the '&' operand to ensure that all '0's in the mask 504 * the '&' operand to ensure that all '0's in the mask
478 * are retained (much unlike the allow and auditallow cases). 505 * are retained (much unlike the allow and auditallow cases).
479 */ 506 */
480 avd->auditdeny &= avtab_auditdeny(&node->datum); 507 avd->auditdeny &= node->datum.data;
481 if ( (__u32) (AVTAB_AUDITALLOW|AVTAB_ENABLED) == 508 if ( (u16) (AVTAB_AUDITALLOW|AVTAB_ENABLED) ==
482 (node->datum.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) 509 (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED)))
483 avd->auditallow |= avtab_auditallow(&node->datum); 510 avd->auditallow |= node->datum.data;
484 } 511 }
485 return; 512 return;
486} 513}
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index d8ce9cc0b9f1..d515154128cc 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -196,8 +196,9 @@ int ebitmap_read(struct ebitmap *e, void *fp)
196{ 196{
197 int rc; 197 int rc;
198 struct ebitmap_node *n, *l; 198 struct ebitmap_node *n, *l;
199 u32 buf[3], mapsize, count, i; 199 __le32 buf[3];
200 u64 map; 200 u32 mapsize, count, i;
201 __le64 map;
201 202
202 ebitmap_init(e); 203 ebitmap_init(e);
203 204
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 471370233fd9..8bf41055a6cb 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -32,11 +32,41 @@ struct ebitmap {
32#define ebitmap_length(e) ((e)->highbit) 32#define ebitmap_length(e) ((e)->highbit)
33#define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0) 33#define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0)
34 34
35static inline unsigned int ebitmap_start(struct ebitmap *e,
36 struct ebitmap_node **n)
37{
38 *n = e->node;
39 return ebitmap_startbit(e);
40}
41
35static inline void ebitmap_init(struct ebitmap *e) 42static inline void ebitmap_init(struct ebitmap *e)
36{ 43{
37 memset(e, 0, sizeof(*e)); 44 memset(e, 0, sizeof(*e));
38} 45}
39 46
47static inline unsigned int ebitmap_next(struct ebitmap_node **n,
48 unsigned int bit)
49{
50 if ((bit == ((*n)->startbit + MAPSIZE - 1)) &&
51 (*n)->next) {
52 *n = (*n)->next;
53 return (*n)->startbit;
54 }
55
56 return (bit+1);
57}
58
59static inline int ebitmap_node_get_bit(struct ebitmap_node * n,
60 unsigned int bit)
61{
62 if (n->map & (MAPBIT << (bit - n->startbit)))
63 return 1;
64 return 0;
65}
66
67#define ebitmap_for_each_bit(e, n, bit) \
68 for (bit = ebitmap_start(e, &n); bit < ebitmap_length(e); bit = ebitmap_next(&n, bit)) \
69
40int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); 70int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2);
41int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); 71int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
42int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2); 72int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2);
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index d4c32c39ccc9..aaefac2921f1 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -27,6 +27,7 @@
27int mls_compute_context_len(struct context * context) 27int mls_compute_context_len(struct context * context)
28{ 28{
29 int i, l, len, range; 29 int i, l, len, range;
30 struct ebitmap_node *node;
30 31
31 if (!selinux_mls_enabled) 32 if (!selinux_mls_enabled)
32 return 0; 33 return 0;
@@ -36,24 +37,24 @@ int mls_compute_context_len(struct context * context)
36 range = 0; 37 range = 0;
37 len += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 38 len += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]);
38 39
39 for (i = 1; i <= ebitmap_length(&context->range.level[l].cat); i++) { 40 ebitmap_for_each_bit(&context->range.level[l].cat, node, i) {
40 if (ebitmap_get_bit(&context->range.level[l].cat, i - 1)) { 41 if (ebitmap_node_get_bit(node, i)) {
41 if (range) { 42 if (range) {
42 range++; 43 range++;
43 continue; 44 continue;
44 } 45 }
45 46
46 len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1; 47 len += strlen(policydb.p_cat_val_to_name[i]) + 1;
47 range++; 48 range++;
48 } else { 49 } else {
49 if (range > 1) 50 if (range > 1)
50 len += strlen(policydb.p_cat_val_to_name[i - 2]) + 1; 51 len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1;
51 range = 0; 52 range = 0;
52 } 53 }
53 } 54 }
54 /* Handle case where last category is the end of range */ 55 /* Handle case where last category is the end of range */
55 if (range > 1) 56 if (range > 1)
56 len += strlen(policydb.p_cat_val_to_name[i - 2]) + 1; 57 len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1;
57 58
58 if (l == 0) { 59 if (l == 0) {
59 if (mls_level_eq(&context->range.level[0], 60 if (mls_level_eq(&context->range.level[0],
@@ -77,6 +78,7 @@ void mls_sid_to_context(struct context *context,
77{ 78{
78 char *scontextp; 79 char *scontextp;
79 int i, l, range, wrote_sep; 80 int i, l, range, wrote_sep;
81 struct ebitmap_node *node;
80 82
81 if (!selinux_mls_enabled) 83 if (!selinux_mls_enabled)
82 return; 84 return;
@@ -94,8 +96,8 @@ void mls_sid_to_context(struct context *context,
94 scontextp += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 96 scontextp += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]);
95 97
96 /* categories */ 98 /* categories */
97 for (i = 1; i <= ebitmap_length(&context->range.level[l].cat); i++) { 99 ebitmap_for_each_bit(&context->range.level[l].cat, node, i) {
98 if (ebitmap_get_bit(&context->range.level[l].cat, i - 1)) { 100 if (ebitmap_node_get_bit(node, i)) {
99 if (range) { 101 if (range) {
100 range++; 102 range++;
101 continue; 103 continue;
@@ -106,8 +108,8 @@ void mls_sid_to_context(struct context *context,
106 wrote_sep = 1; 108 wrote_sep = 1;
107 } else 109 } else
108 *scontextp++ = ','; 110 *scontextp++ = ',';
109 strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]); 111 strcpy(scontextp, policydb.p_cat_val_to_name[i]);
110 scontextp += strlen(policydb.p_cat_val_to_name[i - 1]); 112 scontextp += strlen(policydb.p_cat_val_to_name[i]);
111 range++; 113 range++;
112 } else { 114 } else {
113 if (range > 1) { 115 if (range > 1) {
@@ -116,8 +118,8 @@ void mls_sid_to_context(struct context *context,
116 else 118 else
117 *scontextp++ = ','; 119 *scontextp++ = ',';
118 120
119 strcpy(scontextp, policydb.p_cat_val_to_name[i - 2]); 121 strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]);
120 scontextp += strlen(policydb.p_cat_val_to_name[i - 2]); 122 scontextp += strlen(policydb.p_cat_val_to_name[i - 1]);
121 } 123 }
122 range = 0; 124 range = 0;
123 } 125 }
@@ -130,8 +132,8 @@ void mls_sid_to_context(struct context *context,
130 else 132 else
131 *scontextp++ = ','; 133 *scontextp++ = ',';
132 134
133 strcpy(scontextp, policydb.p_cat_val_to_name[i - 2]); 135 strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]);
134 scontextp += strlen(policydb.p_cat_val_to_name[i - 2]); 136 scontextp += strlen(policydb.p_cat_val_to_name[i - 1]);
135 } 137 }
136 138
137 if (l == 0) { 139 if (l == 0) {
@@ -157,6 +159,7 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
157{ 159{
158 struct level_datum *levdatum; 160 struct level_datum *levdatum;
159 struct user_datum *usrdatum; 161 struct user_datum *usrdatum;
162 struct ebitmap_node *node;
160 int i, l; 163 int i, l;
161 164
162 if (!selinux_mls_enabled) 165 if (!selinux_mls_enabled)
@@ -179,11 +182,11 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
179 if (!levdatum) 182 if (!levdatum)
180 return 0; 183 return 0;
181 184
182 for (i = 1; i <= ebitmap_length(&c->range.level[l].cat); i++) { 185 ebitmap_for_each_bit(&c->range.level[l].cat, node, i) {
183 if (ebitmap_get_bit(&c->range.level[l].cat, i - 1)) { 186 if (ebitmap_node_get_bit(node, i)) {
184 if (i > p->p_cats.nprim) 187 if (i > p->p_cats.nprim)
185 return 0; 188 return 0;
186 if (!ebitmap_get_bit(&levdatum->level->cat, i - 1)) 189 if (!ebitmap_get_bit(&levdatum->level->cat, i))
187 /* 190 /*
188 * Category may not be associated with 191 * Category may not be associated with
189 * sensitivity in low level. 192 * sensitivity in low level.
@@ -468,6 +471,7 @@ int mls_convert_context(struct policydb *oldp,
468 struct level_datum *levdatum; 471 struct level_datum *levdatum;
469 struct cat_datum *catdatum; 472 struct cat_datum *catdatum;
470 struct ebitmap bitmap; 473 struct ebitmap bitmap;
474 struct ebitmap_node *node;
471 int l, i; 475 int l, i;
472 476
473 if (!selinux_mls_enabled) 477 if (!selinux_mls_enabled)
@@ -482,12 +486,12 @@ int mls_convert_context(struct policydb *oldp,
482 c->range.level[l].sens = levdatum->level->sens; 486 c->range.level[l].sens = levdatum->level->sens;
483 487
484 ebitmap_init(&bitmap); 488 ebitmap_init(&bitmap);
485 for (i = 1; i <= ebitmap_length(&c->range.level[l].cat); i++) { 489 ebitmap_for_each_bit(&c->range.level[l].cat, node, i) {
486 if (ebitmap_get_bit(&c->range.level[l].cat, i - 1)) { 490 if (ebitmap_node_get_bit(node, i)) {
487 int rc; 491 int rc;
488 492
489 catdatum = hashtab_search(newp->p_cats.table, 493 catdatum = hashtab_search(newp->p_cats.table,
490 oldp->p_cat_val_to_name[i - 1]); 494 oldp->p_cat_val_to_name[i]);
491 if (!catdatum) 495 if (!catdatum)
492 return -EINVAL; 496 return -EINVAL;
493 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); 497 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 785c33cf4864..0a758323a9cf 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -91,6 +91,11 @@ static struct policydb_compat_info policydb_compat[] = {
91 .sym_num = SYM_NUM, 91 .sym_num = SYM_NUM,
92 .ocon_num = OCON_NUM, 92 .ocon_num = OCON_NUM,
93 }, 93 },
94 {
95 .version = POLICYDB_VERSION_AVTAB,
96 .sym_num = SYM_NUM,
97 .ocon_num = OCON_NUM,
98 },
94}; 99};
95 100
96static struct policydb_compat_info *policydb_lookup_compat(int version) 101static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -584,6 +589,9 @@ void policydb_destroy(struct policydb *p)
584 struct ocontext *c, *ctmp; 589 struct ocontext *c, *ctmp;
585 struct genfs *g, *gtmp; 590 struct genfs *g, *gtmp;
586 int i; 591 int i;
592 struct role_allow *ra, *lra = NULL;
593 struct role_trans *tr, *ltr = NULL;
594 struct range_trans *rt, *lrt = NULL;
587 595
588 for (i = 0; i < SYM_NUM; i++) { 596 for (i = 0; i < SYM_NUM; i++) {
589 hashtab_map(p->symtab[i].table, destroy_f[i], NULL); 597 hashtab_map(p->symtab[i].table, destroy_f[i], NULL);
@@ -624,6 +632,28 @@ void policydb_destroy(struct policydb *p)
624 632
625 cond_policydb_destroy(p); 633 cond_policydb_destroy(p);
626 634
635 for (tr = p->role_tr; tr; tr = tr->next) {
636 if (ltr) kfree(ltr);
637 ltr = tr;
638 }
639 if (ltr) kfree(ltr);
640
641 for (ra = p->role_allow; ra; ra = ra -> next) {
642 if (lra) kfree(lra);
643 lra = ra;
644 }
645 if (lra) kfree(lra);
646
647 for (rt = p->range_tr; rt; rt = rt -> next) {
648 if (lrt) kfree(lrt);
649 lrt = rt;
650 }
651 if (lrt) kfree(lrt);
652
653 for (i = 0; i < p->p_types.nprim; i++)
654 ebitmap_destroy(&p->type_attr_map[i]);
655 kfree(p->type_attr_map);
656
627 return; 657 return;
628} 658}
629 659
@@ -714,7 +744,8 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
714 */ 744 */
715static int mls_read_range_helper(struct mls_range *r, void *fp) 745static int mls_read_range_helper(struct mls_range *r, void *fp)
716{ 746{
717 u32 buf[2], items; 747 __le32 buf[2];
748 u32 items;
718 int rc; 749 int rc;
719 750
720 rc = next_entry(buf, fp, sizeof(u32)); 751 rc = next_entry(buf, fp, sizeof(u32));
@@ -775,7 +806,7 @@ static int context_read_and_validate(struct context *c,
775 struct policydb *p, 806 struct policydb *p,
776 void *fp) 807 void *fp)
777{ 808{
778 u32 buf[3]; 809 __le32 buf[3];
779 int rc; 810 int rc;
780 811
781 rc = next_entry(buf, fp, sizeof buf); 812 rc = next_entry(buf, fp, sizeof buf);
@@ -815,7 +846,8 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
815 char *key = NULL; 846 char *key = NULL;
816 struct perm_datum *perdatum; 847 struct perm_datum *perdatum;
817 int rc; 848 int rc;
818 u32 buf[2], len; 849 __le32 buf[2];
850 u32 len;
819 851
820 perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL); 852 perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL);
821 if (!perdatum) { 853 if (!perdatum) {
@@ -855,7 +887,8 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
855{ 887{
856 char *key = NULL; 888 char *key = NULL;
857 struct common_datum *comdatum; 889 struct common_datum *comdatum;
858 u32 buf[4], len, nel; 890 __le32 buf[4];
891 u32 len, nel;
859 int i, rc; 892 int i, rc;
860 893
861 comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL); 894 comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL);
@@ -909,7 +942,8 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
909{ 942{
910 struct constraint_node *c, *lc; 943 struct constraint_node *c, *lc;
911 struct constraint_expr *e, *le; 944 struct constraint_expr *e, *le;
912 u32 buf[3], nexpr; 945 __le32 buf[3];
946 u32 nexpr;
913 int rc, i, j, depth; 947 int rc, i, j, depth;
914 948
915 lc = NULL; 949 lc = NULL;
@@ -993,7 +1027,8 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
993{ 1027{
994 char *key = NULL; 1028 char *key = NULL;
995 struct class_datum *cladatum; 1029 struct class_datum *cladatum;
996 u32 buf[6], len, len2, ncons, nel; 1030 __le32 buf[6];
1031 u32 len, len2, ncons, nel;
997 int i, rc; 1032 int i, rc;
998 1033
999 cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL); 1034 cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL);
@@ -1087,7 +1122,8 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1087 char *key = NULL; 1122 char *key = NULL;
1088 struct role_datum *role; 1123 struct role_datum *role;
1089 int rc; 1124 int rc;
1090 u32 buf[2], len; 1125 __le32 buf[2];
1126 u32 len;
1091 1127
1092 role = kmalloc(sizeof(*role), GFP_KERNEL); 1128 role = kmalloc(sizeof(*role), GFP_KERNEL);
1093 if (!role) { 1129 if (!role) {
@@ -1147,7 +1183,8 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1147 char *key = NULL; 1183 char *key = NULL;
1148 struct type_datum *typdatum; 1184 struct type_datum *typdatum;
1149 int rc; 1185 int rc;
1150 u32 buf[3], len; 1186 __le32 buf[3];
1187 u32 len;
1151 1188
1152 typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL); 1189 typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL);
1153 if (!typdatum) { 1190 if (!typdatum) {
@@ -1191,7 +1228,7 @@ bad:
1191 */ 1228 */
1192static int mls_read_level(struct mls_level *lp, void *fp) 1229static int mls_read_level(struct mls_level *lp, void *fp)
1193{ 1230{
1194 u32 buf[1]; 1231 __le32 buf[1];
1195 int rc; 1232 int rc;
1196 1233
1197 memset(lp, 0, sizeof(*lp)); 1234 memset(lp, 0, sizeof(*lp));
@@ -1219,7 +1256,8 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1219 char *key = NULL; 1256 char *key = NULL;
1220 struct user_datum *usrdatum; 1257 struct user_datum *usrdatum;
1221 int rc; 1258 int rc;
1222 u32 buf[2], len; 1259 __le32 buf[2];
1260 u32 len;
1223 1261
1224 usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL); 1262 usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL);
1225 if (!usrdatum) { 1263 if (!usrdatum) {
@@ -1273,7 +1311,8 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
1273 char *key = NULL; 1311 char *key = NULL;
1274 struct level_datum *levdatum; 1312 struct level_datum *levdatum;
1275 int rc; 1313 int rc;
1276 u32 buf[2], len; 1314 __le32 buf[2];
1315 u32 len;
1277 1316
1278 levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC); 1317 levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC);
1279 if (!levdatum) { 1318 if (!levdatum) {
@@ -1324,7 +1363,8 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
1324 char *key = NULL; 1363 char *key = NULL;
1325 struct cat_datum *catdatum; 1364 struct cat_datum *catdatum;
1326 int rc; 1365 int rc;
1327 u32 buf[3], len; 1366 __le32 buf[3];
1367 u32 len;
1328 1368
1329 catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC); 1369 catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC);
1330 if (!catdatum) { 1370 if (!catdatum) {
@@ -1387,7 +1427,8 @@ int policydb_read(struct policydb *p, void *fp)
1387 struct ocontext *l, *c, *newc; 1427 struct ocontext *l, *c, *newc;
1388 struct genfs *genfs_p, *genfs, *newgenfs; 1428 struct genfs *genfs_p, *genfs, *newgenfs;
1389 int i, j, rc; 1429 int i, j, rc;
1390 u32 buf[8], len, len2, config, nprim, nel, nel2; 1430 __le32 buf[8];
1431 u32 len, len2, config, nprim, nel, nel2;
1391 char *policydb_str; 1432 char *policydb_str;
1392 struct policydb_compat_info *info; 1433 struct policydb_compat_info *info;
1393 struct range_trans *rt, *lrt; 1434 struct range_trans *rt, *lrt;
@@ -1403,17 +1444,14 @@ int policydb_read(struct policydb *p, void *fp)
1403 if (rc < 0) 1444 if (rc < 0)
1404 goto bad; 1445 goto bad;
1405 1446
1406 for (i = 0; i < 2; i++) 1447 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) {
1407 buf[i] = le32_to_cpu(buf[i]);
1408
1409 if (buf[0] != POLICYDB_MAGIC) {
1410 printk(KERN_ERR "security: policydb magic number 0x%x does " 1448 printk(KERN_ERR "security: policydb magic number 0x%x does "
1411 "not match expected magic number 0x%x\n", 1449 "not match expected magic number 0x%x\n",
1412 buf[0], POLICYDB_MAGIC); 1450 le32_to_cpu(buf[0]), POLICYDB_MAGIC);
1413 goto bad; 1451 goto bad;
1414 } 1452 }
1415 1453
1416 len = buf[1]; 1454 len = le32_to_cpu(buf[1]);
1417 if (len != strlen(POLICYDB_STRING)) { 1455 if (len != strlen(POLICYDB_STRING)) {
1418 printk(KERN_ERR "security: policydb string length %d does not " 1456 printk(KERN_ERR "security: policydb string length %d does not "
1419 "match expected length %Zu\n", 1457 "match expected length %Zu\n",
@@ -1448,19 +1486,17 @@ int policydb_read(struct policydb *p, void *fp)
1448 rc = next_entry(buf, fp, sizeof(u32)*4); 1486 rc = next_entry(buf, fp, sizeof(u32)*4);
1449 if (rc < 0) 1487 if (rc < 0)
1450 goto bad; 1488 goto bad;
1451 for (i = 0; i < 4; i++)
1452 buf[i] = le32_to_cpu(buf[i]);
1453 1489
1454 p->policyvers = buf[0]; 1490 p->policyvers = le32_to_cpu(buf[0]);
1455 if (p->policyvers < POLICYDB_VERSION_MIN || 1491 if (p->policyvers < POLICYDB_VERSION_MIN ||
1456 p->policyvers > POLICYDB_VERSION_MAX) { 1492 p->policyvers > POLICYDB_VERSION_MAX) {
1457 printk(KERN_ERR "security: policydb version %d does not match " 1493 printk(KERN_ERR "security: policydb version %d does not match "
1458 "my version range %d-%d\n", 1494 "my version range %d-%d\n",
1459 buf[0], POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); 1495 le32_to_cpu(buf[0]), POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
1460 goto bad; 1496 goto bad;
1461 } 1497 }
1462 1498
1463 if ((buf[1] & POLICYDB_CONFIG_MLS)) { 1499 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
1464 if (ss_initialized && !selinux_mls_enabled) { 1500 if (ss_initialized && !selinux_mls_enabled) {
1465 printk(KERN_ERR "Cannot switch between non-MLS and MLS " 1501 printk(KERN_ERR "Cannot switch between non-MLS and MLS "
1466 "policies\n"); 1502 "policies\n");
@@ -1489,9 +1525,11 @@ int policydb_read(struct policydb *p, void *fp)
1489 goto bad; 1525 goto bad;
1490 } 1526 }
1491 1527
1492 if (buf[2] != info->sym_num || buf[3] != info->ocon_num) { 1528 if (le32_to_cpu(buf[2]) != info->sym_num ||
1529 le32_to_cpu(buf[3]) != info->ocon_num) {
1493 printk(KERN_ERR "security: policydb table sizes (%d,%d) do " 1530 printk(KERN_ERR "security: policydb table sizes (%d,%d) do "
1494 "not match mine (%d,%d)\n", buf[2], buf[3], 1531 "not match mine (%d,%d)\n", le32_to_cpu(buf[2]),
1532 le32_to_cpu(buf[3]),
1495 info->sym_num, info->ocon_num); 1533 info->sym_num, info->ocon_num);
1496 goto bad; 1534 goto bad;
1497 } 1535 }
@@ -1511,7 +1549,7 @@ int policydb_read(struct policydb *p, void *fp)
1511 p->symtab[i].nprim = nprim; 1549 p->symtab[i].nprim = nprim;
1512 } 1550 }
1513 1551
1514 rc = avtab_read(&p->te_avtab, fp, config); 1552 rc = avtab_read(&p->te_avtab, fp, p->policyvers);
1515 if (rc) 1553 if (rc)
1516 goto bad; 1554 goto bad;
1517 1555
@@ -1825,6 +1863,21 @@ int policydb_read(struct policydb *p, void *fp)
1825 } 1863 }
1826 } 1864 }
1827 1865
1866 p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL);
1867 if (!p->type_attr_map)
1868 goto bad;
1869
1870 for (i = 0; i < p->p_types.nprim; i++) {
1871 ebitmap_init(&p->type_attr_map[i]);
1872 if (p->policyvers >= POLICYDB_VERSION_AVTAB) {
1873 if (ebitmap_read(&p->type_attr_map[i], fp))
1874 goto bad;
1875 }
1876 /* add the type itself as the degenerate case */
1877 if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))
1878 goto bad;
1879 }
1880
1828 rc = 0; 1881 rc = 0;
1829out: 1882out:
1830 return rc; 1883 return rc;
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 2470e2a1a1c3..b1340711f721 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -237,6 +237,9 @@ struct policydb {
237 /* range transitions */ 237 /* range transitions */
238 struct range_trans *range_tr; 238 struct range_trans *range_tr;
239 239
240 /* type -> attribute reverse mapping */
241 struct ebitmap *type_attr_map;
242
240 unsigned int policyvers; 243 unsigned int policyvers;
241}; 244};
242 245
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 45d317044cb2..aecdded55e74 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -266,8 +266,11 @@ static int context_struct_compute_av(struct context *scontext,
266 struct constraint_node *constraint; 266 struct constraint_node *constraint;
267 struct role_allow *ra; 267 struct role_allow *ra;
268 struct avtab_key avkey; 268 struct avtab_key avkey;
269 struct avtab_datum *avdatum; 269 struct avtab_node *node;
270 struct class_datum *tclass_datum; 270 struct class_datum *tclass_datum;
271 struct ebitmap *sattr, *tattr;
272 struct ebitmap_node *snode, *tnode;
273 unsigned int i, j;
271 274
272 /* 275 /*
273 * Remap extended Netlink classes for old policy versions. 276 * Remap extended Netlink classes for old policy versions.
@@ -300,21 +303,34 @@ static int context_struct_compute_av(struct context *scontext,
300 * If a specific type enforcement rule was defined for 303 * If a specific type enforcement rule was defined for
301 * this permission check, then use it. 304 * this permission check, then use it.
302 */ 305 */
303 avkey.source_type = scontext->type;
304 avkey.target_type = tcontext->type;
305 avkey.target_class = tclass; 306 avkey.target_class = tclass;
306 avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_AV); 307 avkey.specified = AVTAB_AV;
307 if (avdatum) { 308 sattr = &policydb.type_attr_map[scontext->type - 1];
308 if (avdatum->specified & AVTAB_ALLOWED) 309 tattr = &policydb.type_attr_map[tcontext->type - 1];
309 avd->allowed = avtab_allowed(avdatum); 310 ebitmap_for_each_bit(sattr, snode, i) {
310 if (avdatum->specified & AVTAB_AUDITDENY) 311 if (!ebitmap_node_get_bit(snode, i))
311 avd->auditdeny = avtab_auditdeny(avdatum); 312 continue;
312 if (avdatum->specified & AVTAB_AUDITALLOW) 313 ebitmap_for_each_bit(tattr, tnode, j) {
313 avd->auditallow = avtab_auditallow(avdatum); 314 if (!ebitmap_node_get_bit(tnode, j))
314 } 315 continue;
316 avkey.source_type = i + 1;
317 avkey.target_type = j + 1;
318 for (node = avtab_search_node(&policydb.te_avtab, &avkey);
319 node != NULL;
320 node = avtab_search_node_next(node, avkey.specified)) {
321 if (node->key.specified == AVTAB_ALLOWED)
322 avd->allowed |= node->datum.data;
323 else if (node->key.specified == AVTAB_AUDITALLOW)
324 avd->auditallow |= node->datum.data;
325 else if (node->key.specified == AVTAB_AUDITDENY)
326 avd->auditdeny &= node->datum.data;
327 }
315 328
316 /* Check conditional av table for additional permissions */ 329 /* Check conditional av table for additional permissions */
317 cond_compute_av(&policydb.te_cond_avtab, &avkey, avd); 330 cond_compute_av(&policydb.te_cond_avtab, &avkey, avd);
331
332 }
333 }
318 334
319 /* 335 /*
320 * Remove any permissions prohibited by a constraint (this includes 336 * Remove any permissions prohibited by a constraint (this includes
@@ -797,7 +813,6 @@ static int security_compute_sid(u32 ssid,
797 struct avtab_key avkey; 813 struct avtab_key avkey;
798 struct avtab_datum *avdatum; 814 struct avtab_datum *avdatum;
799 struct avtab_node *node; 815 struct avtab_node *node;
800 unsigned int type_change = 0;
801 int rc = 0; 816 int rc = 0;
802 817
803 if (!ss_initialized) { 818 if (!ss_initialized) {
@@ -862,33 +877,23 @@ static int security_compute_sid(u32 ssid,
862 avkey.source_type = scontext->type; 877 avkey.source_type = scontext->type;
863 avkey.target_type = tcontext->type; 878 avkey.target_type = tcontext->type;
864 avkey.target_class = tclass; 879 avkey.target_class = tclass;
865 avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_TYPE); 880 avkey.specified = specified;
881 avdatum = avtab_search(&policydb.te_avtab, &avkey);
866 882
867 /* If no permanent rule, also check for enabled conditional rules */ 883 /* If no permanent rule, also check for enabled conditional rules */
868 if(!avdatum) { 884 if(!avdatum) {
869 node = avtab_search_node(&policydb.te_cond_avtab, &avkey, specified); 885 node = avtab_search_node(&policydb.te_cond_avtab, &avkey);
870 for (; node != NULL; node = avtab_search_node_next(node, specified)) { 886 for (; node != NULL; node = avtab_search_node_next(node, specified)) {
871 if (node->datum.specified & AVTAB_ENABLED) { 887 if (node->key.specified & AVTAB_ENABLED) {
872 avdatum = &node->datum; 888 avdatum = &node->datum;
873 break; 889 break;
874 } 890 }
875 } 891 }
876 } 892 }
877 893
878 type_change = (avdatum && (avdatum->specified & specified)); 894 if (avdatum) {
879 if (type_change) {
880 /* Use the type from the type transition/member/change rule. */ 895 /* Use the type from the type transition/member/change rule. */
881 switch (specified) { 896 newcontext.type = avdatum->data;
882 case AVTAB_TRANSITION:
883 newcontext.type = avtab_transition(avdatum);
884 break;
885 case AVTAB_MEMBER:
886 newcontext.type = avtab_member(avdatum);
887 break;
888 case AVTAB_CHANGE:
889 newcontext.type = avtab_change(avdatum);
890 break;
891 }
892 } 897 }
893 898
894 /* Check for class-specific changes. */ 899 /* Check for class-specific changes. */
@@ -1502,6 +1507,7 @@ int security_get_user_sids(u32 fromsid,
1502 struct user_datum *user; 1507 struct user_datum *user;
1503 struct role_datum *role; 1508 struct role_datum *role;
1504 struct av_decision avd; 1509 struct av_decision avd;
1510 struct ebitmap_node *rnode, *tnode;
1505 int rc = 0, i, j; 1511 int rc = 0, i, j;
1506 1512
1507 if (!ss_initialized) { 1513 if (!ss_initialized) {
@@ -1532,13 +1538,13 @@ int security_get_user_sids(u32 fromsid,
1532 } 1538 }
1533 memset(mysids, 0, maxnel*sizeof(*mysids)); 1539 memset(mysids, 0, maxnel*sizeof(*mysids));
1534 1540
1535 for (i = ebitmap_startbit(&user->roles); i < ebitmap_length(&user->roles); i++) { 1541 ebitmap_for_each_bit(&user->roles, rnode, i) {
1536 if (!ebitmap_get_bit(&user->roles, i)) 1542 if (!ebitmap_node_get_bit(rnode, i))
1537 continue; 1543 continue;
1538 role = policydb.role_val_to_struct[i]; 1544 role = policydb.role_val_to_struct[i];
1539 usercon.role = i+1; 1545 usercon.role = i+1;
1540 for (j = ebitmap_startbit(&role->types); j < ebitmap_length(&role->types); j++) { 1546 ebitmap_for_each_bit(&role->types, tnode, j) {
1541 if (!ebitmap_get_bit(&role->types, j)) 1547 if (!ebitmap_node_get_bit(tnode, j))
1542 continue; 1548 continue;
1543 usercon.type = j+1; 1549 usercon.type = j+1;
1544 1550