aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2011-05-24 09:20:19 -0400
committerJames Morris <jmorris@namei.org>2011-05-24 09:20:19 -0400
commitb7b57551bbda1390959207f79f2038aa7adb72ae (patch)
treed591a08e7e45615b51d8b5ee1634a29920f62c3f /security
parent434d42cfd05a7cc452457a81d2029540cba12150 (diff)
parent7a627e3b9a2bd0f06945bbe64bcf403e788ecf6e (diff)
Merge branch 'master' of git://git.infradead.org/users/eparis/selinux into for-linus
Conflicts: lib/flex_array.c security/selinux/avc.c security/selinux/hooks.c security/selinux/ss/policydb.c security/smack/smack_lsm.c Manually resolve conflicts. Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
-rw-r--r--security/lsm_audit.c59
-rw-r--r--security/selinux/avc.c2
-rw-r--r--security/selinux/hooks.c92
-rw-r--r--security/selinux/include/security.h9
-rw-r--r--security/selinux/netnode.c1
-rw-r--r--security/selinux/selinuxfs.c28
-rw-r--r--security/selinux/ss/policydb.c244
-rw-r--r--security/selinux/ss/policydb.h12
-rw-r--r--security/selinux/ss/services.c72
-rw-r--r--security/smack/smack.h11
-rw-r--r--security/smack/smack_lsm.c48
11 files changed, 370 insertions, 208 deletions
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 908aa712816..893af8a2fa1 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -210,7 +210,6 @@ static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
210static void dump_common_audit_data(struct audit_buffer *ab, 210static void dump_common_audit_data(struct audit_buffer *ab,
211 struct common_audit_data *a) 211 struct common_audit_data *a)
212{ 212{
213 struct inode *inode = NULL;
214 struct task_struct *tsk = current; 213 struct task_struct *tsk = current;
215 214
216 if (a->tsk) 215 if (a->tsk)
@@ -229,33 +228,47 @@ static void dump_common_audit_data(struct audit_buffer *ab,
229 case LSM_AUDIT_DATA_CAP: 228 case LSM_AUDIT_DATA_CAP:
230 audit_log_format(ab, " capability=%d ", a->u.cap); 229 audit_log_format(ab, " capability=%d ", a->u.cap);
231 break; 230 break;
232 case LSM_AUDIT_DATA_FS: 231 case LSM_AUDIT_DATA_PATH: {
233 if (a->u.fs.path.dentry) { 232 struct inode *inode;
234 struct dentry *dentry = a->u.fs.path.dentry; 233
235 if (a->u.fs.path.mnt) { 234 audit_log_d_path(ab, "path=", &a->u.path);
236 audit_log_d_path(ab, "path=", &a->u.fs.path); 235
237 } else { 236 inode = a->u.path.dentry->d_inode;
238 audit_log_format(ab, " name=");
239 audit_log_untrustedstring(ab,
240 dentry->d_name.name);
241 }
242 inode = dentry->d_inode;
243 } else if (a->u.fs.inode) {
244 struct dentry *dentry;
245 inode = a->u.fs.inode;
246 dentry = d_find_alias(inode);
247 if (dentry) {
248 audit_log_format(ab, " name=");
249 audit_log_untrustedstring(ab,
250 dentry->d_name.name);
251 dput(dentry);
252 }
253 }
254 if (inode) 237 if (inode)
255 audit_log_format(ab, " dev=%s ino=%lu", 238 audit_log_format(ab, " dev=%s ino=%lu",
256 inode->i_sb->s_id, 239 inode->i_sb->s_id,
257 inode->i_ino); 240 inode->i_ino);
258 break; 241 break;
242 }
243 case LSM_AUDIT_DATA_DENTRY: {
244 struct inode *inode;
245
246 audit_log_format(ab, " name=");
247 audit_log_untrustedstring(ab, a->u.dentry->d_name.name);
248
249 inode = a->u.dentry->d_inode;
250 if (inode)
251 audit_log_format(ab, " dev=%s ino=%lu",
252 inode->i_sb->s_id,
253 inode->i_ino);
254 break;
255 }
256 case LSM_AUDIT_DATA_INODE: {
257 struct dentry *dentry;
258 struct inode *inode;
259
260 inode = a->u.inode;
261 dentry = d_find_alias(inode);
262 if (dentry) {
263 audit_log_format(ab, " name=");
264 audit_log_untrustedstring(ab,
265 dentry->d_name.name);
266 dput(dentry);
267 }
268 audit_log_format(ab, " dev=%s ino=%lu", inode->i_sb->s_id,
269 inode->i_ino);
270 break;
271 }
259 case LSM_AUDIT_DATA_TASK: 272 case LSM_AUDIT_DATA_TASK:
260 tsk = a->u.tsk; 273 tsk = a->u.tsk;
261 if (tsk && tsk->pid) { 274 if (tsk && tsk->pid) {
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 3d2715fd35e..fcb89cb0f22 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -526,7 +526,7 @@ int avc_audit(u32 ssid, u32 tsid,
526 * during retry. However this is logically just as if the operation 526 * during retry. However this is logically just as if the operation
527 * happened a little later. 527 * happened a little later.
528 */ 528 */
529 if ((a->type == LSM_AUDIT_DATA_FS) && 529 if ((a->type == LSM_AUDIT_DATA_INODE) &&
530 (flags & IPERM_FLAG_RCU)) 530 (flags & IPERM_FLAG_RCU))
531 return -ECHILD; 531 return -ECHILD;
532 532
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8fb24884300..a0d38459d65 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -990,6 +990,7 @@ static void selinux_write_opts(struct seq_file *m,
990 continue; 990 continue;
991 default: 991 default:
992 BUG(); 992 BUG();
993 return;
993 }; 994 };
994 /* we need a comma before each option */ 995 /* we need a comma before each option */
995 seq_putc(m, ','); 996 seq_putc(m, ',');
@@ -1443,6 +1444,7 @@ static int task_has_capability(struct task_struct *tsk,
1443 printk(KERN_ERR 1444 printk(KERN_ERR
1444 "SELinux: out of range capability %d\n", cap); 1445 "SELinux: out of range capability %d\n", cap);
1445 BUG(); 1446 BUG();
1447 return -EINVAL;
1446 } 1448 }
1447 1449
1448 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); 1450 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
@@ -1487,8 +1489,8 @@ static int inode_has_perm(const struct cred *cred,
1487 1489
1488 if (!adp) { 1490 if (!adp) {
1489 adp = &ad; 1491 adp = &ad;
1490 COMMON_AUDIT_DATA_INIT(&ad, FS); 1492 COMMON_AUDIT_DATA_INIT(&ad, INODE);
1491 ad.u.fs.inode = inode; 1493 ad.u.inode = inode;
1492 } 1494 }
1493 1495
1494 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); 1496 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
@@ -1498,16 +1500,29 @@ static int inode_has_perm(const struct cred *cred,
1498 the dentry to help the auditing code to more easily generate the 1500 the dentry to help the auditing code to more easily generate the
1499 pathname if needed. */ 1501 pathname if needed. */
1500static inline int dentry_has_perm(const struct cred *cred, 1502static inline int dentry_has_perm(const struct cred *cred,
1501 struct vfsmount *mnt,
1502 struct dentry *dentry, 1503 struct dentry *dentry,
1503 u32 av) 1504 u32 av)
1504{ 1505{
1505 struct inode *inode = dentry->d_inode; 1506 struct inode *inode = dentry->d_inode;
1506 struct common_audit_data ad; 1507 struct common_audit_data ad;
1507 1508
1508 COMMON_AUDIT_DATA_INIT(&ad, FS); 1509 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1509 ad.u.fs.path.mnt = mnt; 1510 ad.u.dentry = dentry;
1510 ad.u.fs.path.dentry = dentry; 1511 return inode_has_perm(cred, inode, av, &ad, 0);
1512}
1513
1514/* Same as inode_has_perm, but pass explicit audit data containing
1515 the path to help the auditing code to more easily generate the
1516 pathname if needed. */
1517static inline int path_has_perm(const struct cred *cred,
1518 struct path *path,
1519 u32 av)
1520{
1521 struct inode *inode = path->dentry->d_inode;
1522 struct common_audit_data ad;
1523
1524 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1525 ad.u.path = *path;
1511 return inode_has_perm(cred, inode, av, &ad, 0); 1526 return inode_has_perm(cred, inode, av, &ad, 0);
1512} 1527}
1513 1528
@@ -1529,8 +1544,8 @@ static int file_has_perm(const struct cred *cred,
1529 u32 sid = cred_sid(cred); 1544 u32 sid = cred_sid(cred);
1530 int rc; 1545 int rc;
1531 1546
1532 COMMON_AUDIT_DATA_INIT(&ad, FS); 1547 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1533 ad.u.fs.path = file->f_path; 1548 ad.u.path = file->f_path;
1534 1549
1535 if (sid != fsec->sid) { 1550 if (sid != fsec->sid) {
1536 rc = avc_has_perm(sid, fsec->sid, 1551 rc = avc_has_perm(sid, fsec->sid,
@@ -1568,8 +1583,8 @@ static int may_create(struct inode *dir,
1568 sid = tsec->sid; 1583 sid = tsec->sid;
1569 newsid = tsec->create_sid; 1584 newsid = tsec->create_sid;
1570 1585
1571 COMMON_AUDIT_DATA_INIT(&ad, FS); 1586 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1572 ad.u.fs.path.dentry = dentry; 1587 ad.u.dentry = dentry;
1573 1588
1574 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, 1589 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
1575 DIR__ADD_NAME | DIR__SEARCH, 1590 DIR__ADD_NAME | DIR__SEARCH,
@@ -1621,8 +1636,8 @@ static int may_link(struct inode *dir,
1621 dsec = dir->i_security; 1636 dsec = dir->i_security;
1622 isec = dentry->d_inode->i_security; 1637 isec = dentry->d_inode->i_security;
1623 1638
1624 COMMON_AUDIT_DATA_INIT(&ad, FS); 1639 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1625 ad.u.fs.path.dentry = dentry; 1640 ad.u.dentry = dentry;
1626 1641
1627 av = DIR__SEARCH; 1642 av = DIR__SEARCH;
1628 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); 1643 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
@@ -1667,9 +1682,9 @@ static inline int may_rename(struct inode *old_dir,
1667 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); 1682 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
1668 new_dsec = new_dir->i_security; 1683 new_dsec = new_dir->i_security;
1669 1684
1670 COMMON_AUDIT_DATA_INIT(&ad, FS); 1685 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1671 1686
1672 ad.u.fs.path.dentry = old_dentry; 1687 ad.u.dentry = old_dentry;
1673 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, 1688 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
1674 DIR__REMOVE_NAME | DIR__SEARCH, &ad); 1689 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1675 if (rc) 1690 if (rc)
@@ -1685,7 +1700,7 @@ static inline int may_rename(struct inode *old_dir,
1685 return rc; 1700 return rc;
1686 } 1701 }
1687 1702
1688 ad.u.fs.path.dentry = new_dentry; 1703 ad.u.dentry = new_dentry;
1689 av = DIR__ADD_NAME | DIR__SEARCH; 1704 av = DIR__ADD_NAME | DIR__SEARCH;
1690 if (new_dentry->d_inode) 1705 if (new_dentry->d_inode)
1691 av |= DIR__REMOVE_NAME; 1706 av |= DIR__REMOVE_NAME;
@@ -1895,7 +1910,7 @@ static int selinux_quota_on(struct dentry *dentry)
1895{ 1910{
1896 const struct cred *cred = current_cred(); 1911 const struct cred *cred = current_cred();
1897 1912
1898 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); 1913 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
1899} 1914}
1900 1915
1901static int selinux_syslog(int type) 1916static int selinux_syslog(int type)
@@ -1992,8 +2007,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
1992 return rc; 2007 return rc;
1993 } 2008 }
1994 2009
1995 COMMON_AUDIT_DATA_INIT(&ad, FS); 2010 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1996 ad.u.fs.path = bprm->file->f_path; 2011 ad.u.path = bprm->file->f_path;
1997 2012
1998 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) 2013 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
1999 new_tsec->sid = old_tsec->sid; 2014 new_tsec->sid = old_tsec->sid;
@@ -2121,7 +2136,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2121 2136
2122 /* Revalidate access to inherited open files. */ 2137 /* Revalidate access to inherited open files. */
2123 2138
2124 COMMON_AUDIT_DATA_INIT(&ad, FS); 2139 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2125 2140
2126 spin_lock(&files->file_lock); 2141 spin_lock(&files->file_lock);
2127 for (;;) { 2142 for (;;) {
@@ -2469,8 +2484,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
2469 if (flags & MS_KERNMOUNT) 2484 if (flags & MS_KERNMOUNT)
2470 return 0; 2485 return 0;
2471 2486
2472 COMMON_AUDIT_DATA_INIT(&ad, FS); 2487 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2473 ad.u.fs.path.dentry = sb->s_root; 2488 ad.u.dentry = sb->s_root;
2474 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); 2489 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
2475} 2490}
2476 2491
@@ -2479,8 +2494,8 @@ static int selinux_sb_statfs(struct dentry *dentry)
2479 const struct cred *cred = current_cred(); 2494 const struct cred *cred = current_cred();
2480 struct common_audit_data ad; 2495 struct common_audit_data ad;
2481 2496
2482 COMMON_AUDIT_DATA_INIT(&ad, FS); 2497 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2483 ad.u.fs.path.dentry = dentry->d_sb->s_root; 2498 ad.u.dentry = dentry->d_sb->s_root;
2484 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); 2499 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
2485} 2500}
2486 2501
@@ -2496,8 +2511,7 @@ static int selinux_mount(char *dev_name,
2496 return superblock_has_perm(cred, path->mnt->mnt_sb, 2511 return superblock_has_perm(cred, path->mnt->mnt_sb,
2497 FILESYSTEM__REMOUNT, NULL); 2512 FILESYSTEM__REMOUNT, NULL);
2498 else 2513 else
2499 return dentry_has_perm(cred, path->mnt, path->dentry, 2514 return path_has_perm(cred, path, FILE__MOUNTON);
2500 FILE__MOUNTON);
2501} 2515}
2502 2516
2503static int selinux_umount(struct vfsmount *mnt, int flags) 2517static int selinux_umount(struct vfsmount *mnt, int flags)
@@ -2630,14 +2644,14 @@ static int selinux_inode_readlink(struct dentry *dentry)
2630{ 2644{
2631 const struct cred *cred = current_cred(); 2645 const struct cred *cred = current_cred();
2632 2646
2633 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2647 return dentry_has_perm(cred, dentry, FILE__READ);
2634} 2648}
2635 2649
2636static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) 2650static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
2637{ 2651{
2638 const struct cred *cred = current_cred(); 2652 const struct cred *cred = current_cred();
2639 2653
2640 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2654 return dentry_has_perm(cred, dentry, FILE__READ);
2641} 2655}
2642 2656
2643static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags) 2657static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags)
@@ -2654,8 +2668,8 @@ static int selinux_inode_permission(struct inode *inode, int mask, unsigned flag
2654 if (!mask) 2668 if (!mask)
2655 return 0; 2669 return 0;
2656 2670
2657 COMMON_AUDIT_DATA_INIT(&ad, FS); 2671 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2658 ad.u.fs.inode = inode; 2672 ad.u.inode = inode;
2659 2673
2660 if (from_access) 2674 if (from_access)
2661 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS; 2675 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
@@ -2680,16 +2694,20 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2680 2694
2681 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | 2695 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
2682 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) 2696 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
2683 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2697 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2684 2698
2685 return dentry_has_perm(cred, NULL, dentry, FILE__WRITE); 2699 return dentry_has_perm(cred, dentry, FILE__WRITE);
2686} 2700}
2687 2701
2688static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 2702static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2689{ 2703{
2690 const struct cred *cred = current_cred(); 2704 const struct cred *cred = current_cred();
2705 struct path path;
2706
2707 path.dentry = dentry;
2708 path.mnt = mnt;
2691 2709
2692 return dentry_has_perm(cred, mnt, dentry, FILE__GETATTR); 2710 return path_has_perm(cred, &path, FILE__GETATTR);
2693} 2711}
2694 2712
2695static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) 2713static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
@@ -2710,7 +2728,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
2710 2728
2711 /* Not an attribute we recognize, so just check the 2729 /* Not an attribute we recognize, so just check the
2712 ordinary setattr permission. */ 2730 ordinary setattr permission. */
2713 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2731 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2714} 2732}
2715 2733
2716static int selinux_inode_setxattr(struct dentry *dentry, const char *name, 2734static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
@@ -2733,8 +2751,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2733 if (!inode_owner_or_capable(inode)) 2751 if (!inode_owner_or_capable(inode))
2734 return -EPERM; 2752 return -EPERM;
2735 2753
2736 COMMON_AUDIT_DATA_INIT(&ad, FS); 2754 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2737 ad.u.fs.path.dentry = dentry; 2755 ad.u.dentry = dentry;
2738 2756
2739 rc = avc_has_perm(sid, isec->sid, isec->sclass, 2757 rc = avc_has_perm(sid, isec->sid, isec->sclass,
2740 FILE__RELABELFROM, &ad); 2758 FILE__RELABELFROM, &ad);
@@ -2797,14 +2815,14 @@ static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
2797{ 2815{
2798 const struct cred *cred = current_cred(); 2816 const struct cred *cred = current_cred();
2799 2817
2800 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2818 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2801} 2819}
2802 2820
2803static int selinux_inode_listxattr(struct dentry *dentry) 2821static int selinux_inode_listxattr(struct dentry *dentry)
2804{ 2822{
2805 const struct cred *cred = current_cred(); 2823 const struct cred *cred = current_cred();
2806 2824
2807 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2825 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2808} 2826}
2809 2827
2810static int selinux_inode_removexattr(struct dentry *dentry, const char *name) 2828static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 348eb00cb66..3ba4feba048 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -30,13 +30,14 @@
30#define POLICYDB_VERSION_PERMISSIVE 23 30#define POLICYDB_VERSION_PERMISSIVE 23
31#define POLICYDB_VERSION_BOUNDARY 24 31#define POLICYDB_VERSION_BOUNDARY 24
32#define POLICYDB_VERSION_FILENAME_TRANS 25 32#define POLICYDB_VERSION_FILENAME_TRANS 25
33#define POLICYDB_VERSION_ROLETRANS 26
33 34
34/* Range of policy versions we understand*/ 35/* Range of policy versions we understand*/
35#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 36#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
36#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX 37#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
37#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE 38#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
38#else 39#else
39#define POLICYDB_VERSION_MAX POLICYDB_VERSION_FILENAME_TRANS 40#define POLICYDB_VERSION_MAX POLICYDB_VERSION_ROLETRANS
40#endif 41#endif
41 42
42/* Mask for just the mount related flags */ 43/* Mask for just the mount related flags */
@@ -85,7 +86,7 @@ extern int selinux_policycap_openperm;
85int security_mls_enabled(void); 86int security_mls_enabled(void);
86 87
87int security_load_policy(void *data, size_t len); 88int security_load_policy(void *data, size_t len);
88int security_read_policy(void **data, ssize_t *len); 89int security_read_policy(void **data, size_t *len);
89size_t security_policydb_len(void); 90size_t security_policydb_len(void);
90 91
91int security_policycap_supported(unsigned int req_cap); 92int security_policycap_supported(unsigned int req_cap);
@@ -111,8 +112,8 @@ void security_compute_av_user(u32 ssid, u32 tsid,
111int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, 112int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
112 const struct qstr *qstr, u32 *out_sid); 113 const struct qstr *qstr, u32 *out_sid);
113 114
114int security_transition_sid_user(u32 ssid, u32 tsid, 115int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
115 u16 tclass, u32 *out_sid); 116 const char *objname, u32 *out_sid);
116 117
117int security_member_sid(u32 ssid, u32 tsid, 118int security_member_sid(u32 ssid, u32 tsid,
118 u16 tclass, u32 *out_sid); 119 u16 tclass, u32 *out_sid);
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 65ebfe954f8..3618251d0fd 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -141,6 +141,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
141 break; 141 break;
142 default: 142 default:
143 BUG(); 143 BUG();
144 return NULL;
144 } 145 }
145 146
146 list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list) 147 list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 2d3373b2e25..77d44138864 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -28,6 +28,7 @@
28#include <linux/percpu.h> 28#include <linux/percpu.h>
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <linux/kobject.h>
31 32
32/* selinuxfs pseudo filesystem for exporting the security policy API. 33/* selinuxfs pseudo filesystem for exporting the security policy API.
33 Based on the proc code and the fs/nfsd/nfsctl.c code. */ 34 Based on the proc code and the fs/nfsd/nfsctl.c code. */
@@ -753,11 +754,13 @@ out:
753static ssize_t sel_write_create(struct file *file, char *buf, size_t size) 754static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
754{ 755{
755 char *scon = NULL, *tcon = NULL; 756 char *scon = NULL, *tcon = NULL;
757 char *namebuf = NULL, *objname = NULL;
756 u32 ssid, tsid, newsid; 758 u32 ssid, tsid, newsid;
757 u16 tclass; 759 u16 tclass;
758 ssize_t length; 760 ssize_t length;
759 char *newcon = NULL; 761 char *newcon = NULL;
760 u32 len; 762 u32 len;
763 int nargs;
761 764
762 length = task_has_security(current, SECURITY__COMPUTE_CREATE); 765 length = task_has_security(current, SECURITY__COMPUTE_CREATE);
763 if (length) 766 if (length)
@@ -773,9 +776,17 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
773 if (!tcon) 776 if (!tcon)
774 goto out; 777 goto out;
775 778
779 length = -ENOMEM;
780 namebuf = kzalloc(size + 1, GFP_KERNEL);
781 if (!namebuf)
782 goto out;
783
776 length = -EINVAL; 784 length = -EINVAL;
777 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 785 nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
786 if (nargs < 3 || nargs > 4)
778 goto out; 787 goto out;
788 if (nargs == 4)
789 objname = namebuf;
779 790
780 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 791 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
781 if (length) 792 if (length)
@@ -785,7 +796,8 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
785 if (length) 796 if (length)
786 goto out; 797 goto out;
787 798
788 length = security_transition_sid_user(ssid, tsid, tclass, &newsid); 799 length = security_transition_sid_user(ssid, tsid, tclass,
800 objname, &newsid);
789 if (length) 801 if (length)
790 goto out; 802 goto out;
791 803
@@ -804,6 +816,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
804 length = len; 816 length = len;
805out: 817out:
806 kfree(newcon); 818 kfree(newcon);
819 kfree(namebuf);
807 kfree(tcon); 820 kfree(tcon);
808 kfree(scon); 821 kfree(scon);
809 return length; 822 return length;
@@ -1901,6 +1914,7 @@ static struct file_system_type sel_fs_type = {
1901}; 1914};
1902 1915
1903struct vfsmount *selinuxfs_mount; 1916struct vfsmount *selinuxfs_mount;
1917static struct kobject *selinuxfs_kobj;
1904 1918
1905static int __init init_sel_fs(void) 1919static int __init init_sel_fs(void)
1906{ 1920{
@@ -1908,9 +1922,16 @@ static int __init init_sel_fs(void)
1908 1922
1909 if (!selinux_enabled) 1923 if (!selinux_enabled)
1910 return 0; 1924 return 0;
1925
1926 selinuxfs_kobj = kobject_create_and_add("selinux", fs_kobj);
1927 if (!selinuxfs_kobj)
1928 return -ENOMEM;
1929
1911 err = register_filesystem(&sel_fs_type); 1930 err = register_filesystem(&sel_fs_type);
1912 if (err) 1931 if (err) {
1932 kobject_put(selinuxfs_kobj);
1913 return err; 1933 return err;
1934 }
1914 1935
1915 selinuxfs_mount = kern_mount(&sel_fs_type); 1936 selinuxfs_mount = kern_mount(&sel_fs_type);
1916 if (IS_ERR(selinuxfs_mount)) { 1937 if (IS_ERR(selinuxfs_mount)) {
@@ -1927,6 +1948,7 @@ __initcall(init_sel_fs);
1927#ifdef CONFIG_SECURITY_SELINUX_DISABLE 1948#ifdef CONFIG_SECURITY_SELINUX_DISABLE
1928void exit_sel_fs(void) 1949void exit_sel_fs(void)
1929{ 1950{
1951 kobject_put(selinuxfs_kobj);
1930 unregister_filesystem(&sel_fs_type); 1952 unregister_filesystem(&sel_fs_type);
1931} 1953}
1932#endif 1954#endif
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 7102457661d..102e9ec1b77 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -128,6 +128,11 @@ static struct policydb_compat_info policydb_compat[] = {
128 .sym_num = SYM_NUM, 128 .sym_num = SYM_NUM,
129 .ocon_num = OCON_NUM, 129 .ocon_num = OCON_NUM,
130 }, 130 },
131 {
132 .version = POLICYDB_VERSION_ROLETRANS,
133 .sym_num = SYM_NUM,
134 .ocon_num = OCON_NUM,
135 },
131}; 136};
132 137
133static struct policydb_compat_info *policydb_lookup_compat(int version) 138static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -179,6 +184,43 @@ out:
179 return rc; 184 return rc;
180} 185}
181 186
187static u32 filenametr_hash(struct hashtab *h, const void *k)
188{
189 const struct filename_trans *ft = k;
190 unsigned long hash;
191 unsigned int byte_num;
192 unsigned char focus;
193
194 hash = ft->stype ^ ft->ttype ^ ft->tclass;
195
196 byte_num = 0;
197 while ((focus = ft->name[byte_num++]))
198 hash = partial_name_hash(focus, hash);
199 return hash & (h->size - 1);
200}
201
202static int filenametr_cmp(struct hashtab *h, const void *k1, const void *k2)
203{
204 const struct filename_trans *ft1 = k1;
205 const struct filename_trans *ft2 = k2;
206 int v;
207
208 v = ft1->stype - ft2->stype;
209 if (v)
210 return v;
211
212 v = ft1->ttype - ft2->ttype;
213 if (v)
214 return v;
215
216 v = ft1->tclass - ft2->tclass;
217 if (v)
218 return v;
219
220 return strcmp(ft1->name, ft2->name);
221
222}
223
182static u32 rangetr_hash(struct hashtab *h, const void *k) 224static u32 rangetr_hash(struct hashtab *h, const void *k)
183{ 225{
184 const struct range_trans *key = k; 226 const struct range_trans *key = k;
@@ -231,15 +273,22 @@ static int policydb_init(struct policydb *p)
231 if (rc) 273 if (rc)
232 goto out; 274 goto out;
233 275
276 p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
277 if (!p->filename_trans)
278 goto out;
279
234 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); 280 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
235 if (!p->range_tr) 281 if (!p->range_tr)
236 goto out; 282 goto out;
237 283
284 ebitmap_init(&p->filename_trans_ttypes);
238 ebitmap_init(&p->policycaps); 285 ebitmap_init(&p->policycaps);
239 ebitmap_init(&p->permissive_map); 286 ebitmap_init(&p->permissive_map);
240 287
241 return 0; 288 return 0;
242out: 289out:
290 hashtab_destroy(p->filename_trans);
291 hashtab_destroy(p->range_tr);
243 for (i = 0; i < SYM_NUM; i++) 292 for (i = 0; i < SYM_NUM; i++)
244 hashtab_destroy(p->symtab[i].table); 293 hashtab_destroy(p->symtab[i].table);
245 return rc; 294 return rc;
@@ -417,32 +466,26 @@ static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
417}; 466};
418 467
419#ifdef DEBUG_HASHES 468#ifdef DEBUG_HASHES
420static void symtab_hash_eval(struct symtab *s) 469static void hash_eval(struct hashtab *h, const char *hash_name)
421{ 470{
422 int i; 471 struct hashtab_info info;
423
424 for (i = 0; i < SYM_NUM; i++) {
425 struct hashtab *h = s[i].table;
426 struct hashtab_info info;
427 472
428 hashtab_stat(h, &info); 473 hashtab_stat(h, &info);
429 printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, " 474 printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, "
430 "longest chain length %d\n", symtab_name[i], h->nel, 475 "longest chain length %d\n", hash_name, h->nel,
431 info.slots_used, h->size, info.max_chain_len); 476 info.slots_used, h->size, info.max_chain_len);
432 }
433} 477}
434 478
435static void rangetr_hash_eval(struct hashtab *h) 479static void symtab_hash_eval(struct symtab *s)
436{ 480{
437 struct hashtab_info info; 481 int i;
438 482
439 hashtab_stat(h, &info); 483 for (i = 0; i < SYM_NUM; i++)
440 printk(KERN_DEBUG "SELinux: rangetr: %d entries and %d/%d buckets used, " 484 hash_eval(s[i].table, symtab_name[i]);
441 "longest chain length %d\n", h->nel,
442 info.slots_used, h->size, info.max_chain_len);
443} 485}
486
444#else 487#else
445static inline void rangetr_hash_eval(struct hashtab *h) 488static inline void hash_eval(struct hashtab *h, char *hash_name)
446{ 489{
447} 490}
448#endif 491#endif
@@ -675,6 +718,16 @@ static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
675 cat_destroy, 718 cat_destroy,
676}; 719};
677 720
721static int filenametr_destroy(void *key, void *datum, void *p)
722{
723 struct filename_trans *ft = key;
724 kfree(ft->name);
725 kfree(key);
726 kfree(datum);
727 cond_resched();
728 return 0;
729}
730
678static int range_tr_destroy(void *key, void *datum, void *p) 731static int range_tr_destroy(void *key, void *datum, void *p)
679{ 732{
680 struct mls_range *rt = datum; 733 struct mls_range *rt = datum;
@@ -709,7 +762,6 @@ void policydb_destroy(struct policydb *p)
709 int i; 762 int i;
710 struct role_allow *ra, *lra = NULL; 763 struct role_allow *ra, *lra = NULL;
711 struct role_trans *tr, *ltr = NULL; 764 struct role_trans *tr, *ltr = NULL;
712 struct filename_trans *ft, *nft;
713 765
714 for (i = 0; i < SYM_NUM; i++) { 766 for (i = 0; i < SYM_NUM; i++) {
715 cond_resched(); 767 cond_resched();
@@ -773,6 +825,9 @@ void policydb_destroy(struct policydb *p)
773 } 825 }
774 kfree(lra); 826 kfree(lra);
775 827
828 hashtab_map(p->filename_trans, filenametr_destroy, NULL);
829 hashtab_destroy(p->filename_trans);
830
776 hashtab_map(p->range_tr, range_tr_destroy, NULL); 831 hashtab_map(p->range_tr, range_tr_destroy, NULL);
777 hashtab_destroy(p->range_tr); 832 hashtab_destroy(p->range_tr);
778 833
@@ -788,14 +843,7 @@ void policydb_destroy(struct policydb *p)
788 flex_array_free(p->type_attr_map_array); 843 flex_array_free(p->type_attr_map_array);
789 } 844 }
790 845
791 ft = p->filename_trans; 846 ebitmap_destroy(&p->filename_trans_ttypes);
792 while (ft) {
793 nft = ft->next;
794 kfree(ft->name);
795 kfree(ft);
796 ft = nft;
797 }
798
799 ebitmap_destroy(&p->policycaps); 847 ebitmap_destroy(&p->policycaps);
800 ebitmap_destroy(&p->permissive_map); 848 ebitmap_destroy(&p->permissive_map);
801 849
@@ -1795,7 +1843,7 @@ static int range_read(struct policydb *p, void *fp)
1795 rt = NULL; 1843 rt = NULL;
1796 r = NULL; 1844 r = NULL;
1797 } 1845 }
1798 rangetr_hash_eval(p->range_tr); 1846 hash_eval(p->range_tr, "rangetr");
1799 rc = 0; 1847 rc = 0;
1800out: 1848out:
1801 kfree(rt); 1849 kfree(rt);
@@ -1805,9 +1853,10 @@ out:
1805 1853
1806static int filename_trans_read(struct policydb *p, void *fp) 1854static int filename_trans_read(struct policydb *p, void *fp)
1807{ 1855{
1808 struct filename_trans *ft, *last; 1856 struct filename_trans *ft;
1809 u32 nel, len; 1857 struct filename_trans_datum *otype;
1810 char *name; 1858 char *name;
1859 u32 nel, len;
1811 __le32 buf[4]; 1860 __le32 buf[4];
1812 int rc, i; 1861 int rc, i;
1813 1862
@@ -1816,25 +1865,23 @@ static int filename_trans_read(struct policydb *p, void *fp)
1816 1865
1817 rc = next_entry(buf, fp, sizeof(u32)); 1866 rc = next_entry(buf, fp, sizeof(u32));
1818 if (rc) 1867 if (rc)
1819 goto out; 1868 return rc;
1820 nel = le32_to_cpu(buf[0]); 1869 nel = le32_to_cpu(buf[0]);
1821 1870
1822 last = p->filename_trans;
1823 while (last && last->next)
1824 last = last->next;
1825
1826 for (i = 0; i < nel; i++) { 1871 for (i = 0; i < nel; i++) {
1872 ft = NULL;
1873 otype = NULL;
1874 name = NULL;
1875
1827 rc = -ENOMEM; 1876 rc = -ENOMEM;
1828 ft = kzalloc(sizeof(*ft), GFP_KERNEL); 1877 ft = kzalloc(sizeof(*ft), GFP_KERNEL);
1829 if (!ft) 1878 if (!ft)
1830 goto out; 1879 goto out;
1831 1880
1832 /* add it to the tail of the list */ 1881 rc = -ENOMEM;
1833 if (!last) 1882 otype = kmalloc(sizeof(*otype), GFP_KERNEL);
1834 p->filename_trans = ft; 1883 if (!otype)
1835 else 1884 goto out;
1836 last->next = ft;
1837 last = ft;
1838 1885
1839 /* length of the path component string */ 1886 /* length of the path component string */
1840 rc = next_entry(buf, fp, sizeof(u32)); 1887 rc = next_entry(buf, fp, sizeof(u32));
@@ -1862,10 +1909,22 @@ static int filename_trans_read(struct policydb *p, void *fp)
1862 ft->stype = le32_to_cpu(buf[0]); 1909 ft->stype = le32_to_cpu(buf[0]);
1863 ft->ttype = le32_to_cpu(buf[1]); 1910 ft->ttype = le32_to_cpu(buf[1]);
1864 ft->tclass = le32_to_cpu(buf[2]); 1911 ft->tclass = le32_to_cpu(buf[2]);
1865 ft->otype = le32_to_cpu(buf[3]); 1912
1913 otype->otype = le32_to_cpu(buf[3]);
1914
1915 rc = ebitmap_set_bit(&p->filename_trans_ttypes, ft->ttype, 1);
1916 if (rc)
1917 goto out;
1918
1919 hashtab_insert(p->filename_trans, ft, otype);
1866 } 1920 }
1867 rc = 0; 1921 hash_eval(p->filename_trans, "filenametr");
1922 return 0;
1868out: 1923out:
1924 kfree(ft);
1925 kfree(name);
1926 kfree(otype);
1927
1869 return rc; 1928 return rc;
1870} 1929}
1871 1930
@@ -2266,6 +2325,11 @@ int policydb_read(struct policydb *p, void *fp)
2266 p->symtab[i].nprim = nprim; 2325 p->symtab[i].nprim = nprim;
2267 } 2326 }
2268 2327
2328 rc = -EINVAL;
2329 p->process_class = string_to_security_class(p, "process");
2330 if (!p->process_class)
2331 goto bad;
2332
2269 rc = avtab_read(&p->te_avtab, fp, p); 2333 rc = avtab_read(&p->te_avtab, fp, p);
2270 if (rc) 2334 if (rc)
2271 goto bad; 2335 goto bad;
@@ -2298,8 +2362,17 @@ int policydb_read(struct policydb *p, void *fp)
2298 tr->role = le32_to_cpu(buf[0]); 2362 tr->role = le32_to_cpu(buf[0]);
2299 tr->type = le32_to_cpu(buf[1]); 2363 tr->type = le32_to_cpu(buf[1]);
2300 tr->new_role = le32_to_cpu(buf[2]); 2364 tr->new_role = le32_to_cpu(buf[2]);
2365 if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2366 rc = next_entry(buf, fp, sizeof(u32));
2367 if (rc)
2368 goto bad;
2369 tr->tclass = le32_to_cpu(buf[0]);
2370 } else
2371 tr->tclass = p->process_class;
2372
2301 if (!policydb_role_isvalid(p, tr->role) || 2373 if (!policydb_role_isvalid(p, tr->role) ||
2302 !policydb_type_isvalid(p, tr->type) || 2374 !policydb_type_isvalid(p, tr->type) ||
2375 !policydb_class_isvalid(p, tr->tclass) ||
2303 !policydb_role_isvalid(p, tr->new_role)) 2376 !policydb_role_isvalid(p, tr->new_role))
2304 goto bad; 2377 goto bad;
2305 ltr = tr; 2378 ltr = tr;
@@ -2341,11 +2414,6 @@ int policydb_read(struct policydb *p, void *fp)
2341 goto bad; 2414 goto bad;
2342 2415
2343 rc = -EINVAL; 2416 rc = -EINVAL;
2344 p->process_class = string_to_security_class(p, "process");
2345 if (!p->process_class)
2346 goto bad;
2347
2348 rc = -EINVAL;
2349 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition"); 2417 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
2350 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition"); 2418 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
2351 if (!p->process_trans_perms) 2419 if (!p->process_trans_perms)
@@ -2517,8 +2585,9 @@ static int cat_write(void *vkey, void *datum, void *ptr)
2517 return 0; 2585 return 0;
2518} 2586}
2519 2587
2520static int role_trans_write(struct role_trans *r, void *fp) 2588static int role_trans_write(struct policydb *p, void *fp)
2521{ 2589{
2590 struct role_trans *r = p->role_tr;
2522 struct role_trans *tr; 2591 struct role_trans *tr;
2523 u32 buf[3]; 2592 u32 buf[3];
2524 size_t nel; 2593 size_t nel;
@@ -2538,6 +2607,12 @@ static int role_trans_write(struct role_trans *r, void *fp)
2538 rc = put_entry(buf, sizeof(u32), 3, fp); 2607 rc = put_entry(buf, sizeof(u32), 3, fp);
2539 if (rc) 2608 if (rc)
2540 return rc; 2609 return rc;
2610 if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2611 buf[0] = cpu_to_le32(tr->tclass);
2612 rc = put_entry(buf, sizeof(u32), 1, fp);
2613 if (rc)
2614 return rc;
2615 }
2541 } 2616 }
2542 2617
2543 return 0; 2618 return 0;
@@ -3045,7 +3120,7 @@ static int genfs_write(struct policydb *p, void *fp)
3045 return 0; 3120 return 0;
3046} 3121}
3047 3122
3048static int range_count(void *key, void *data, void *ptr) 3123static int hashtab_cnt(void *key, void *data, void *ptr)
3049{ 3124{
3050 int *cnt = ptr; 3125 int *cnt = ptr;
3051 *cnt = *cnt + 1; 3126 *cnt = *cnt + 1;
@@ -3093,7 +3168,7 @@ static int range_write(struct policydb *p, void *fp)
3093 3168
3094 /* count the number of entries in the hashtab */ 3169 /* count the number of entries in the hashtab */
3095 nel = 0; 3170 nel = 0;
3096 rc = hashtab_map(p->range_tr, range_count, &nel); 3171 rc = hashtab_map(p->range_tr, hashtab_cnt, &nel);
3097 if (rc) 3172 if (rc)
3098 return rc; 3173 return rc;
3099 3174
@@ -3110,43 +3185,60 @@ static int range_write(struct policydb *p, void *fp)
3110 return 0; 3185 return 0;
3111} 3186}
3112 3187
3113static int filename_trans_write(struct policydb *p, void *fp) 3188static int filename_write_helper(void *key, void *data, void *ptr)
3114{ 3189{
3115 struct filename_trans *ft;
3116 u32 len, nel = 0;
3117 __le32 buf[4]; 3190 __le32 buf[4];
3191 struct filename_trans *ft = key;
3192 struct filename_trans_datum *otype = data;
3193 void *fp = ptr;
3118 int rc; 3194 int rc;
3195 u32 len;
3119 3196
3120 for (ft = p->filename_trans; ft; ft = ft->next) 3197 len = strlen(ft->name);
3121 nel++; 3198 buf[0] = cpu_to_le32(len);
3122
3123 buf[0] = cpu_to_le32(nel);
3124 rc = put_entry(buf, sizeof(u32), 1, fp); 3199 rc = put_entry(buf, sizeof(u32), 1, fp);
3125 if (rc) 3200 if (rc)
3126 return rc; 3201 return rc;
3127 3202
3128 for (ft = p->filename_trans; ft; ft = ft->next) { 3203 rc = put_entry(ft->name, sizeof(char), len, fp);
3129 len = strlen(ft->name); 3204 if (rc)
3130 buf[0] = cpu_to_le32(len); 3205 return rc;
3131 rc = put_entry(buf, sizeof(u32), 1, fp);
3132 if (rc)
3133 return rc;
3134 3206
3135 rc = put_entry(ft->name, sizeof(char), len, fp); 3207 buf[0] = ft->stype;
3136 if (rc) 3208 buf[1] = ft->ttype;
3137 return rc; 3209 buf[2] = ft->tclass;
3210 buf[3] = otype->otype;
3138 3211
3139 buf[0] = ft->stype; 3212 rc = put_entry(buf, sizeof(u32), 4, fp);
3140 buf[1] = ft->ttype; 3213 if (rc)
3141 buf[2] = ft->tclass; 3214 return rc;
3142 buf[3] = ft->otype;
3143 3215
3144 rc = put_entry(buf, sizeof(u32), 4, fp);
3145 if (rc)
3146 return rc;
3147 }
3148 return 0; 3216 return 0;
3149} 3217}
3218
3219static int filename_trans_write(struct policydb *p, void *fp)
3220{
3221 u32 nel;
3222 __le32 buf[1];
3223 int rc;
3224
3225 nel = 0;
3226 rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel);
3227 if (rc)
3228 return rc;
3229
3230 buf[0] = cpu_to_le32(nel);
3231 rc = put_entry(buf, sizeof(u32), 1, fp);
3232 if (rc)
3233 return rc;
3234
3235 rc = hashtab_map(p->filename_trans, filename_write_helper, fp);
3236 if (rc)
3237 return rc;
3238
3239 return 0;
3240}
3241
3150/* 3242/*
3151 * Write the configuration data in a policy database 3243 * Write the configuration data in a policy database
3152 * structure to a policy database binary representation 3244 * structure to a policy database binary representation
@@ -3249,7 +3341,7 @@ int policydb_write(struct policydb *p, void *fp)
3249 if (rc) 3341 if (rc)
3250 return rc; 3342 return rc;
3251 3343
3252 rc = role_trans_write(p->role_tr, fp); 3344 rc = role_trans_write(p, fp);
3253 if (rc) 3345 if (rc)
3254 return rc; 3346 return rc;
3255 3347
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 732ea4a6868..b846c038718 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -72,17 +72,20 @@ struct role_datum {
72 72
73struct role_trans { 73struct role_trans {
74 u32 role; /* current role */ 74 u32 role; /* current role */
75 u32 type; /* program executable type */ 75 u32 type; /* program executable type, or new object type */
76 u32 tclass; /* process class, or new object class */
76 u32 new_role; /* new role */ 77 u32 new_role; /* new role */
77 struct role_trans *next; 78 struct role_trans *next;
78}; 79};
79 80
80struct filename_trans { 81struct filename_trans {
81 struct filename_trans *next;
82 u32 stype; /* current process */ 82 u32 stype; /* current process */
83 u32 ttype; /* parent dir context */ 83 u32 ttype; /* parent dir context */
84 u16 tclass; /* class of new object */ 84 u16 tclass; /* class of new object */
85 const char *name; /* last path component */ 85 const char *name; /* last path component */
86};
87
88struct filename_trans_datum {
86 u32 otype; /* expected of new object */ 89 u32 otype; /* expected of new object */
87}; 90};
88 91
@@ -227,7 +230,10 @@ struct policydb {
227 struct role_trans *role_tr; 230 struct role_trans *role_tr;
228 231
229 /* file transitions with the last path component */ 232 /* file transitions with the last path component */
230 struct filename_trans *filename_trans; 233 /* quickly exclude lookups when parent ttype has no rules */
234 struct ebitmap filename_trans_ttypes;
235 /* actual set of filename_trans rules */
236 struct hashtab *filename_trans;
231 237
232 /* bools indexed by (value - 1) */ 238 /* bools indexed by (value - 1) */
233 struct cond_bool_datum **bool_val_to_struct; 239 struct cond_bool_datum **bool_val_to_struct;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 6ef4af47dac..c3e4b52699f 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1359,26 +1359,35 @@ out:
1359} 1359}
1360 1360
1361static void filename_compute_type(struct policydb *p, struct context *newcontext, 1361static void filename_compute_type(struct policydb *p, struct context *newcontext,
1362 u32 scon, u32 tcon, u16 tclass, 1362 u32 stype, u32 ttype, u16 tclass,
1363 const struct qstr *qstr) 1363 const char *objname)
1364{ 1364{
1365 struct filename_trans *ft; 1365 struct filename_trans ft;
1366 for (ft = p->filename_trans; ft; ft = ft->next) { 1366 struct filename_trans_datum *otype;
1367 if (ft->stype == scon && 1367
1368 ft->ttype == tcon && 1368 /*
1369 ft->tclass == tclass && 1369 * Most filename trans rules are going to live in specific directories
1370 !strcmp(ft->name, qstr->name)) { 1370 * like /dev or /var/run. This bitmap will quickly skip rule searches
1371 newcontext->type = ft->otype; 1371 * if the ttype does not contain any rules.
1372 return; 1372 */
1373 } 1373 if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype))
1374 } 1374 return;
1375
1376 ft.stype = stype;
1377 ft.ttype = ttype;
1378 ft.tclass = tclass;
1379 ft.name = objname;
1380
1381 otype = hashtab_search(p->filename_trans, &ft);
1382 if (otype)
1383 newcontext->type = otype->otype;
1375} 1384}
1376 1385
1377static int security_compute_sid(u32 ssid, 1386static int security_compute_sid(u32 ssid,
1378 u32 tsid, 1387 u32 tsid,
1379 u16 orig_tclass, 1388 u16 orig_tclass,
1380 u32 specified, 1389 u32 specified,
1381 const struct qstr *qstr, 1390 const char *objname,
1382 u32 *out_sid, 1391 u32 *out_sid,
1383 bool kern) 1392 bool kern)
1384{ 1393{
@@ -1478,23 +1487,21 @@ static int security_compute_sid(u32 ssid,
1478 newcontext.type = avdatum->data; 1487 newcontext.type = avdatum->data;
1479 } 1488 }
1480 1489
1481 /* if we have a qstr this is a file trans check so check those rules */ 1490 /* if we have a objname this is a file trans check so check those rules */
1482 if (qstr) 1491 if (objname)
1483 filename_compute_type(&policydb, &newcontext, scontext->type, 1492 filename_compute_type(&policydb, &newcontext, scontext->type,
1484 tcontext->type, tclass, qstr); 1493 tcontext->type, tclass, objname);
1485 1494
1486 /* Check for class-specific changes. */ 1495 /* Check for class-specific changes. */
1487 if (tclass == policydb.process_class) { 1496 if (specified & AVTAB_TRANSITION) {
1488 if (specified & AVTAB_TRANSITION) { 1497 /* Look for a role transition rule. */
1489 /* Look for a role transition rule. */ 1498 for (roletr = policydb.role_tr; roletr; roletr = roletr->next) {
1490 for (roletr = policydb.role_tr; roletr; 1499 if ((roletr->role == scontext->role) &&
1491 roletr = roletr->next) { 1500 (roletr->type == tcontext->type) &&
1492 if (roletr->role == scontext->role && 1501 (roletr->tclass == tclass)) {
1493 roletr->type == tcontext->type) { 1502 /* Use the role transition rule. */
1494 /* Use the role transition rule. */ 1503 newcontext.role = roletr->new_role;
1495 newcontext.role = roletr->new_role; 1504 break;
1496 break;
1497 }
1498 } 1505 }
1499 } 1506 }
1500 } 1507 }
@@ -1541,13 +1548,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
1541 const struct qstr *qstr, u32 *out_sid) 1548 const struct qstr *qstr, u32 *out_sid)
1542{ 1549{
1543 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, 1550 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1544 qstr, out_sid, true); 1551 qstr ? qstr->name : NULL, out_sid, true);
1545} 1552}
1546 1553
1547int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) 1554int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
1555 const char *objname, u32 *out_sid)
1548{ 1556{
1549 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, 1557 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1550 NULL, out_sid, false); 1558 objname, out_sid, false);
1551} 1559}
1552 1560
1553/** 1561/**
@@ -3190,7 +3198,7 @@ out:
3190 * @len: length of data in bytes 3198 * @len: length of data in bytes
3191 * 3199 *
3192 */ 3200 */
3193int security_read_policy(void **data, ssize_t *len) 3201int security_read_policy(void **data, size_t *len)
3194{ 3202{
3195 int rc; 3203 int rc;
3196 struct policy_file fp; 3204 struct policy_file fp;
diff --git a/security/smack/smack.h b/security/smack/smack.h
index b449cfdad21..2b6c6a51612 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -316,22 +316,17 @@ static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a,
316static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a, 316static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a,
317 struct dentry *d) 317 struct dentry *d)
318{ 318{
319 a->a.u.fs.path.dentry = d; 319 a->a.u.dentry = d;
320}
321static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a,
322 struct vfsmount *m)
323{
324 a->a.u.fs.path.mnt = m;
325} 320}
326static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, 321static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a,
327 struct inode *i) 322 struct inode *i)
328{ 323{
329 a->a.u.fs.inode = i; 324 a->a.u.inode = i;
330} 325}
331static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a, 326static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
332 struct path p) 327 struct path p)
333{ 328{
334 a->a.u.fs.path = p; 329 a->a.u.path = p;
335} 330}
336static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, 331static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
337 struct sock *sk) 332 struct sock *sk)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 400a5d5cde6..9831a39c11f 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -383,7 +383,7 @@ static int smack_sb_statfs(struct dentry *dentry)
383 int rc; 383 int rc;
384 struct smk_audit_info ad; 384 struct smk_audit_info ad;
385 385
386 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 386 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
387 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 387 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
388 388
389 rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad); 389 rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
@@ -407,7 +407,7 @@ static int smack_sb_mount(char *dev_name, struct path *path,
407 struct superblock_smack *sbp = path->mnt->mnt_sb->s_security; 407 struct superblock_smack *sbp = path->mnt->mnt_sb->s_security;
408 struct smk_audit_info ad; 408 struct smk_audit_info ad;
409 409
410 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 410 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
411 smk_ad_setfield_u_fs_path(&ad, *path); 411 smk_ad_setfield_u_fs_path(&ad, *path);
412 412
413 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); 413 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
@@ -425,10 +425,13 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
425{ 425{
426 struct superblock_smack *sbp; 426 struct superblock_smack *sbp;
427 struct smk_audit_info ad; 427 struct smk_audit_info ad;
428 struct path path;
428 429
429 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 430 path.dentry = mnt->mnt_root;
430 smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_root); 431 path.mnt = mnt;
431 smk_ad_setfield_u_fs_path_mnt(&ad, mnt); 432
433 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
434 smk_ad_setfield_u_fs_path(&ad, path);
432 435
433 sbp = mnt->mnt_sb->s_security; 436 sbp = mnt->mnt_sb->s_security;
434 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); 437 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
@@ -563,7 +566,7 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
563 struct smk_audit_info ad; 566 struct smk_audit_info ad;
564 int rc; 567 int rc;
565 568
566 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 569 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
567 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); 570 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
568 571
569 isp = smk_of_inode(old_dentry->d_inode); 572 isp = smk_of_inode(old_dentry->d_inode);
@@ -592,7 +595,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
592 struct smk_audit_info ad; 595 struct smk_audit_info ad;
593 int rc; 596 int rc;
594 597
595 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 598 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
596 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 599 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
597 600
598 /* 601 /*
@@ -623,7 +626,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
623 struct smk_audit_info ad; 626 struct smk_audit_info ad;
624 int rc; 627 int rc;
625 628
626 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 629 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
627 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 630 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
628 631
629 /* 632 /*
@@ -663,7 +666,7 @@ static int smack_inode_rename(struct inode *old_inode,
663 char *isp; 666 char *isp;
664 struct smk_audit_info ad; 667 struct smk_audit_info ad;
665 668
666 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 669 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
667 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); 670 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
668 671
669 isp = smk_of_inode(old_dentry->d_inode); 672 isp = smk_of_inode(old_dentry->d_inode);
@@ -700,7 +703,7 @@ static int smack_inode_permission(struct inode *inode, int mask, unsigned flags)
700 /* May be droppable after audit */ 703 /* May be droppable after audit */
701 if (flags & IPERM_FLAG_RCU) 704 if (flags & IPERM_FLAG_RCU)
702 return -ECHILD; 705 return -ECHILD;
703 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 706 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
704 smk_ad_setfield_u_fs_inode(&ad, inode); 707 smk_ad_setfield_u_fs_inode(&ad, inode);
705 return smk_curacc(smk_of_inode(inode), mask, &ad); 708 return smk_curacc(smk_of_inode(inode), mask, &ad);
706} 709}
@@ -720,7 +723,7 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
720 */ 723 */
721 if (iattr->ia_valid & ATTR_FORCE) 724 if (iattr->ia_valid & ATTR_FORCE)
722 return 0; 725 return 0;
723 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 726 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
724 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 727 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
725 728
726 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); 729 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
@@ -736,10 +739,13 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
736static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 739static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
737{ 740{
738 struct smk_audit_info ad; 741 struct smk_audit_info ad;
742 struct path path;
739 743
740 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 744 path.dentry = dentry;
741 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 745 path.mnt = mnt;
742 smk_ad_setfield_u_fs_path_mnt(&ad, mnt); 746
747 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
748 smk_ad_setfield_u_fs_path(&ad, path);
743 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); 749 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
744} 750}
745 751
@@ -784,7 +790,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
784 } else 790 } else
785 rc = cap_inode_setxattr(dentry, name, value, size, flags); 791 rc = cap_inode_setxattr(dentry, name, value, size, flags);
786 792
787 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 793 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
788 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 794 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
789 795
790 if (rc == 0) 796 if (rc == 0)
@@ -845,7 +851,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
845{ 851{
846 struct smk_audit_info ad; 852 struct smk_audit_info ad;
847 853
848 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 854 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
849 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 855 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
850 856
851 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); 857 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
@@ -877,7 +883,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
877 } else 883 } else
878 rc = cap_inode_removexattr(dentry, name); 884 rc = cap_inode_removexattr(dentry, name);
879 885
880 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 886 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
881 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 887 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
882 if (rc == 0) 888 if (rc == 0)
883 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); 889 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
@@ -1047,7 +1053,7 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
1047 int rc = 0; 1053 int rc = 0;
1048 struct smk_audit_info ad; 1054 struct smk_audit_info ad;
1049 1055
1050 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 1056 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1051 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1057 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1052 1058
1053 if (_IOC_DIR(cmd) & _IOC_WRITE) 1059 if (_IOC_DIR(cmd) & _IOC_WRITE)
@@ -1070,8 +1076,8 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
1070{ 1076{
1071 struct smk_audit_info ad; 1077 struct smk_audit_info ad;
1072 1078
1073 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 1079 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1074 smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry); 1080 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1075 return smk_curacc(file->f_security, MAY_WRITE, &ad); 1081 return smk_curacc(file->f_security, MAY_WRITE, &ad);
1076} 1082}
1077 1083
@@ -1089,7 +1095,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
1089 struct smk_audit_info ad; 1095 struct smk_audit_info ad;
1090 int rc; 1096 int rc;
1091 1097
1092 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 1098 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1093 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1099 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1094 1100
1095 switch (cmd) { 1101 switch (cmd) {