aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c113
1 files changed, 68 insertions, 45 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8fb248843009..20219ef5439a 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);
@@ -1474,7 +1476,6 @@ static int inode_has_perm(const struct cred *cred,
1474 unsigned flags) 1476 unsigned flags)
1475{ 1477{
1476 struct inode_security_struct *isec; 1478 struct inode_security_struct *isec;
1477 struct common_audit_data ad;
1478 u32 sid; 1479 u32 sid;
1479 1480
1480 validate_creds(cred); 1481 validate_creds(cred);
@@ -1485,29 +1486,48 @@ static int inode_has_perm(const struct cred *cred,
1485 sid = cred_sid(cred); 1486 sid = cred_sid(cred);
1486 isec = inode->i_security; 1487 isec = inode->i_security;
1487 1488
1488 if (!adp) {
1489 adp = &ad;
1490 COMMON_AUDIT_DATA_INIT(&ad, FS);
1491 ad.u.fs.inode = inode;
1492 }
1493
1494 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); 1489 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
1495} 1490}
1496 1491
1492static int inode_has_perm_noadp(const struct cred *cred,
1493 struct inode *inode,
1494 u32 perms,
1495 unsigned flags)
1496{
1497 struct common_audit_data ad;
1498
1499 COMMON_AUDIT_DATA_INIT(&ad, INODE);
1500 ad.u.inode = inode;
1501 return inode_has_perm(cred, inode, perms, &ad, flags);
1502}
1503
1497/* Same as inode_has_perm, but pass explicit audit data containing 1504/* Same as inode_has_perm, but pass explicit audit data containing
1498 the dentry to help the auditing code to more easily generate the 1505 the dentry to help the auditing code to more easily generate the
1499 pathname if needed. */ 1506 pathname if needed. */
1500static inline int dentry_has_perm(const struct cred *cred, 1507static inline int dentry_has_perm(const struct cred *cred,
1501 struct vfsmount *mnt,
1502 struct dentry *dentry, 1508 struct dentry *dentry,
1503 u32 av) 1509 u32 av)
1504{ 1510{
1505 struct inode *inode = dentry->d_inode; 1511 struct inode *inode = dentry->d_inode;
1506 struct common_audit_data ad; 1512 struct common_audit_data ad;
1507 1513
1508 COMMON_AUDIT_DATA_INIT(&ad, FS); 1514 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1509 ad.u.fs.path.mnt = mnt; 1515 ad.u.dentry = dentry;
1510 ad.u.fs.path.dentry = dentry; 1516 return inode_has_perm(cred, inode, av, &ad, 0);
1517}
1518
1519/* Same as inode_has_perm, but pass explicit audit data containing
1520 the path to help the auditing code to more easily generate the
1521 pathname if needed. */
1522static inline int path_has_perm(const struct cred *cred,
1523 struct path *path,
1524 u32 av)
1525{
1526 struct inode *inode = path->dentry->d_inode;
1527 struct common_audit_data ad;
1528
1529 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1530 ad.u.path = *path;
1511 return inode_has_perm(cred, inode, av, &ad, 0); 1531 return inode_has_perm(cred, inode, av, &ad, 0);
1512} 1532}
1513 1533
@@ -1529,8 +1549,8 @@ static int file_has_perm(const struct cred *cred,
1529 u32 sid = cred_sid(cred); 1549 u32 sid = cred_sid(cred);
1530 int rc; 1550 int rc;
1531 1551
1532 COMMON_AUDIT_DATA_INIT(&ad, FS); 1552 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1533 ad.u.fs.path = file->f_path; 1553 ad.u.path = file->f_path;
1534 1554
1535 if (sid != fsec->sid) { 1555 if (sid != fsec->sid) {
1536 rc = avc_has_perm(sid, fsec->sid, 1556 rc = avc_has_perm(sid, fsec->sid,
@@ -1568,8 +1588,8 @@ static int may_create(struct inode *dir,
1568 sid = tsec->sid; 1588 sid = tsec->sid;
1569 newsid = tsec->create_sid; 1589 newsid = tsec->create_sid;
1570 1590
1571 COMMON_AUDIT_DATA_INIT(&ad, FS); 1591 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1572 ad.u.fs.path.dentry = dentry; 1592 ad.u.dentry = dentry;
1573 1593
1574 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, 1594 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
1575 DIR__ADD_NAME | DIR__SEARCH, 1595 DIR__ADD_NAME | DIR__SEARCH,
@@ -1621,8 +1641,8 @@ static int may_link(struct inode *dir,
1621 dsec = dir->i_security; 1641 dsec = dir->i_security;
1622 isec = dentry->d_inode->i_security; 1642 isec = dentry->d_inode->i_security;
1623 1643
1624 COMMON_AUDIT_DATA_INIT(&ad, FS); 1644 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1625 ad.u.fs.path.dentry = dentry; 1645 ad.u.dentry = dentry;
1626 1646
1627 av = DIR__SEARCH; 1647 av = DIR__SEARCH;
1628 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); 1648 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
@@ -1667,9 +1687,9 @@ static inline int may_rename(struct inode *old_dir,
1667 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); 1687 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
1668 new_dsec = new_dir->i_security; 1688 new_dsec = new_dir->i_security;
1669 1689
1670 COMMON_AUDIT_DATA_INIT(&ad, FS); 1690 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1671 1691
1672 ad.u.fs.path.dentry = old_dentry; 1692 ad.u.dentry = old_dentry;
1673 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, 1693 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
1674 DIR__REMOVE_NAME | DIR__SEARCH, &ad); 1694 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1675 if (rc) 1695 if (rc)
@@ -1685,7 +1705,7 @@ static inline int may_rename(struct inode *old_dir,
1685 return rc; 1705 return rc;
1686 } 1706 }
1687 1707
1688 ad.u.fs.path.dentry = new_dentry; 1708 ad.u.dentry = new_dentry;
1689 av = DIR__ADD_NAME | DIR__SEARCH; 1709 av = DIR__ADD_NAME | DIR__SEARCH;
1690 if (new_dentry->d_inode) 1710 if (new_dentry->d_inode)
1691 av |= DIR__REMOVE_NAME; 1711 av |= DIR__REMOVE_NAME;
@@ -1895,7 +1915,7 @@ static int selinux_quota_on(struct dentry *dentry)
1895{ 1915{
1896 const struct cred *cred = current_cred(); 1916 const struct cred *cred = current_cred();
1897 1917
1898 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); 1918 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
1899} 1919}
1900 1920
1901static int selinux_syslog(int type) 1921static int selinux_syslog(int type)
@@ -1992,8 +2012,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
1992 return rc; 2012 return rc;
1993 } 2013 }
1994 2014
1995 COMMON_AUDIT_DATA_INIT(&ad, FS); 2015 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1996 ad.u.fs.path = bprm->file->f_path; 2016 ad.u.path = bprm->file->f_path;
1997 2017
1998 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) 2018 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
1999 new_tsec->sid = old_tsec->sid; 2019 new_tsec->sid = old_tsec->sid;
@@ -2107,8 +2127,8 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2107 struct tty_file_private, list); 2127 struct tty_file_private, list);
2108 file = file_priv->file; 2128 file = file_priv->file;
2109 inode = file->f_path.dentry->d_inode; 2129 inode = file->f_path.dentry->d_inode;
2110 if (inode_has_perm(cred, inode, 2130 if (inode_has_perm_noadp(cred, inode,
2111 FILE__READ | FILE__WRITE, NULL, 0)) { 2131 FILE__READ | FILE__WRITE, 0)) {
2112 drop_tty = 1; 2132 drop_tty = 1;
2113 } 2133 }
2114 } 2134 }
@@ -2121,7 +2141,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2121 2141
2122 /* Revalidate access to inherited open files. */ 2142 /* Revalidate access to inherited open files. */
2123 2143
2124 COMMON_AUDIT_DATA_INIT(&ad, FS); 2144 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2125 2145
2126 spin_lock(&files->file_lock); 2146 spin_lock(&files->file_lock);
2127 for (;;) { 2147 for (;;) {
@@ -2469,8 +2489,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
2469 if (flags & MS_KERNMOUNT) 2489 if (flags & MS_KERNMOUNT)
2470 return 0; 2490 return 0;
2471 2491
2472 COMMON_AUDIT_DATA_INIT(&ad, FS); 2492 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2473 ad.u.fs.path.dentry = sb->s_root; 2493 ad.u.dentry = sb->s_root;
2474 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); 2494 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
2475} 2495}
2476 2496
@@ -2479,8 +2499,8 @@ static int selinux_sb_statfs(struct dentry *dentry)
2479 const struct cred *cred = current_cred(); 2499 const struct cred *cred = current_cred();
2480 struct common_audit_data ad; 2500 struct common_audit_data ad;
2481 2501
2482 COMMON_AUDIT_DATA_INIT(&ad, FS); 2502 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2483 ad.u.fs.path.dentry = dentry->d_sb->s_root; 2503 ad.u.dentry = dentry->d_sb->s_root;
2484 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); 2504 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
2485} 2505}
2486 2506
@@ -2496,8 +2516,7 @@ static int selinux_mount(char *dev_name,
2496 return superblock_has_perm(cred, path->mnt->mnt_sb, 2516 return superblock_has_perm(cred, path->mnt->mnt_sb,
2497 FILESYSTEM__REMOUNT, NULL); 2517 FILESYSTEM__REMOUNT, NULL);
2498 else 2518 else
2499 return dentry_has_perm(cred, path->mnt, path->dentry, 2519 return path_has_perm(cred, path, FILE__MOUNTON);
2500 FILE__MOUNTON);
2501} 2520}
2502 2521
2503static int selinux_umount(struct vfsmount *mnt, int flags) 2522static int selinux_umount(struct vfsmount *mnt, int flags)
@@ -2630,14 +2649,14 @@ static int selinux_inode_readlink(struct dentry *dentry)
2630{ 2649{
2631 const struct cred *cred = current_cred(); 2650 const struct cred *cred = current_cred();
2632 2651
2633 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2652 return dentry_has_perm(cred, dentry, FILE__READ);
2634} 2653}
2635 2654
2636static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) 2655static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
2637{ 2656{
2638 const struct cred *cred = current_cred(); 2657 const struct cred *cred = current_cred();
2639 2658
2640 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2659 return dentry_has_perm(cred, dentry, FILE__READ);
2641} 2660}
2642 2661
2643static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags) 2662static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags)
@@ -2654,8 +2673,8 @@ static int selinux_inode_permission(struct inode *inode, int mask, unsigned flag
2654 if (!mask) 2673 if (!mask)
2655 return 0; 2674 return 0;
2656 2675
2657 COMMON_AUDIT_DATA_INIT(&ad, FS); 2676 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2658 ad.u.fs.inode = inode; 2677 ad.u.inode = inode;
2659 2678
2660 if (from_access) 2679 if (from_access)
2661 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS; 2680 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
@@ -2680,16 +2699,20 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2680 2699
2681 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | 2700 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
2682 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) 2701 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
2683 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2702 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2684 2703
2685 return dentry_has_perm(cred, NULL, dentry, FILE__WRITE); 2704 return dentry_has_perm(cred, dentry, FILE__WRITE);
2686} 2705}
2687 2706
2688static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 2707static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2689{ 2708{
2690 const struct cred *cred = current_cred(); 2709 const struct cred *cred = current_cred();
2710 struct path path;
2711
2712 path.dentry = dentry;
2713 path.mnt = mnt;
2691 2714
2692 return dentry_has_perm(cred, mnt, dentry, FILE__GETATTR); 2715 return path_has_perm(cred, &path, FILE__GETATTR);
2693} 2716}
2694 2717
2695static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) 2718static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
@@ -2710,7 +2733,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
2710 2733
2711 /* Not an attribute we recognize, so just check the 2734 /* Not an attribute we recognize, so just check the
2712 ordinary setattr permission. */ 2735 ordinary setattr permission. */
2713 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2736 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2714} 2737}
2715 2738
2716static int selinux_inode_setxattr(struct dentry *dentry, const char *name, 2739static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
@@ -2733,8 +2756,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2733 if (!inode_owner_or_capable(inode)) 2756 if (!inode_owner_or_capable(inode))
2734 return -EPERM; 2757 return -EPERM;
2735 2758
2736 COMMON_AUDIT_DATA_INIT(&ad, FS); 2759 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2737 ad.u.fs.path.dentry = dentry; 2760 ad.u.dentry = dentry;
2738 2761
2739 rc = avc_has_perm(sid, isec->sid, isec->sclass, 2762 rc = avc_has_perm(sid, isec->sid, isec->sclass,
2740 FILE__RELABELFROM, &ad); 2763 FILE__RELABELFROM, &ad);
@@ -2797,14 +2820,14 @@ static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
2797{ 2820{
2798 const struct cred *cred = current_cred(); 2821 const struct cred *cred = current_cred();
2799 2822
2800 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2823 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2801} 2824}
2802 2825
2803static int selinux_inode_listxattr(struct dentry *dentry) 2826static int selinux_inode_listxattr(struct dentry *dentry)
2804{ 2827{
2805 const struct cred *cred = current_cred(); 2828 const struct cred *cred = current_cred();
2806 2829
2807 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2830 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2808} 2831}
2809 2832
2810static int selinux_inode_removexattr(struct dentry *dentry, const char *name) 2833static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
@@ -3210,7 +3233,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
3210 * new inode label or new policy. 3233 * new inode label or new policy.
3211 * This check is not redundant - do not remove. 3234 * This check is not redundant - do not remove.
3212 */ 3235 */
3213 return inode_has_perm(cred, inode, open_file_to_av(file), NULL, 0); 3236 return inode_has_perm_noadp(cred, inode, open_file_to_av(file), 0);
3214} 3237}
3215 3238
3216/* task security operations */ 3239/* task security operations */