aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
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/selinux/hooks.c
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/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c92
1 files changed, 55 insertions, 37 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8fb248843009..a0d38459d650 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)