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.c95
1 files changed, 57 insertions, 38 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index f7cf0ea6faea..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,
@@ -1578,7 +1593,8 @@ static int may_create(struct inode *dir,
1578 return rc; 1593 return rc;
1579 1594
1580 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 1595 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
1581 rc = security_transition_sid(sid, dsec->sid, tclass, NULL, &newsid); 1596 rc = security_transition_sid(sid, dsec->sid, tclass,
1597 &dentry->d_name, &newsid);
1582 if (rc) 1598 if (rc)
1583 return rc; 1599 return rc;
1584 } 1600 }
@@ -1620,8 +1636,8 @@ static int may_link(struct inode *dir,
1620 dsec = dir->i_security; 1636 dsec = dir->i_security;
1621 isec = dentry->d_inode->i_security; 1637 isec = dentry->d_inode->i_security;
1622 1638
1623 COMMON_AUDIT_DATA_INIT(&ad, FS); 1639 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1624 ad.u.fs.path.dentry = dentry; 1640 ad.u.dentry = dentry;
1625 1641
1626 av = DIR__SEARCH; 1642 av = DIR__SEARCH;
1627 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); 1643 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
@@ -1666,9 +1682,9 @@ static inline int may_rename(struct inode *old_dir,
1666 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); 1682 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
1667 new_dsec = new_dir->i_security; 1683 new_dsec = new_dir->i_security;
1668 1684
1669 COMMON_AUDIT_DATA_INIT(&ad, FS); 1685 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1670 1686
1671 ad.u.fs.path.dentry = old_dentry; 1687 ad.u.dentry = old_dentry;
1672 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, 1688 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
1673 DIR__REMOVE_NAME | DIR__SEARCH, &ad); 1689 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1674 if (rc) 1690 if (rc)
@@ -1684,7 +1700,7 @@ static inline int may_rename(struct inode *old_dir,
1684 return rc; 1700 return rc;
1685 } 1701 }
1686 1702
1687 ad.u.fs.path.dentry = new_dentry; 1703 ad.u.dentry = new_dentry;
1688 av = DIR__ADD_NAME | DIR__SEARCH; 1704 av = DIR__ADD_NAME | DIR__SEARCH;
1689 if (new_dentry->d_inode) 1705 if (new_dentry->d_inode)
1690 av |= DIR__REMOVE_NAME; 1706 av |= DIR__REMOVE_NAME;
@@ -1894,7 +1910,7 @@ static int selinux_quota_on(struct dentry *dentry)
1894{ 1910{
1895 const struct cred *cred = current_cred(); 1911 const struct cred *cred = current_cred();
1896 1912
1897 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); 1913 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
1898} 1914}
1899 1915
1900static int selinux_syslog(int type) 1916static int selinux_syslog(int type)
@@ -1991,8 +2007,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
1991 return rc; 2007 return rc;
1992 } 2008 }
1993 2009
1994 COMMON_AUDIT_DATA_INIT(&ad, FS); 2010 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1995 ad.u.fs.path = bprm->file->f_path; 2011 ad.u.path = bprm->file->f_path;
1996 2012
1997 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) 2013 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
1998 new_tsec->sid = old_tsec->sid; 2014 new_tsec->sid = old_tsec->sid;
@@ -2120,7 +2136,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2120 2136
2121 /* Revalidate access to inherited open files. */ 2137 /* Revalidate access to inherited open files. */
2122 2138
2123 COMMON_AUDIT_DATA_INIT(&ad, FS); 2139 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2124 2140
2125 spin_lock(&files->file_lock); 2141 spin_lock(&files->file_lock);
2126 for (;;) { 2142 for (;;) {
@@ -2468,8 +2484,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
2468 if (flags & MS_KERNMOUNT) 2484 if (flags & MS_KERNMOUNT)
2469 return 0; 2485 return 0;
2470 2486
2471 COMMON_AUDIT_DATA_INIT(&ad, FS); 2487 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2472 ad.u.fs.path.dentry = sb->s_root; 2488 ad.u.dentry = sb->s_root;
2473 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); 2489 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
2474} 2490}
2475 2491
@@ -2478,8 +2494,8 @@ static int selinux_sb_statfs(struct dentry *dentry)
2478 const struct cred *cred = current_cred(); 2494 const struct cred *cred = current_cred();
2479 struct common_audit_data ad; 2495 struct common_audit_data ad;
2480 2496
2481 COMMON_AUDIT_DATA_INIT(&ad, FS); 2497 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2482 ad.u.fs.path.dentry = dentry->d_sb->s_root; 2498 ad.u.dentry = dentry->d_sb->s_root;
2483 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); 2499 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
2484} 2500}
2485 2501
@@ -2495,8 +2511,7 @@ static int selinux_mount(char *dev_name,
2495 return superblock_has_perm(cred, path->mnt->mnt_sb, 2511 return superblock_has_perm(cred, path->mnt->mnt_sb,
2496 FILESYSTEM__REMOUNT, NULL); 2512 FILESYSTEM__REMOUNT, NULL);
2497 else 2513 else
2498 return dentry_has_perm(cred, path->mnt, path->dentry, 2514 return path_has_perm(cred, path, FILE__MOUNTON);
2499 FILE__MOUNTON);
2500} 2515}
2501 2516
2502static int selinux_umount(struct vfsmount *mnt, int flags) 2517static int selinux_umount(struct vfsmount *mnt, int flags)
@@ -2629,14 +2644,14 @@ static int selinux_inode_readlink(struct dentry *dentry)
2629{ 2644{
2630 const struct cred *cred = current_cred(); 2645 const struct cred *cred = current_cred();
2631 2646
2632 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2647 return dentry_has_perm(cred, dentry, FILE__READ);
2633} 2648}
2634 2649
2635static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) 2650static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
2636{ 2651{
2637 const struct cred *cred = current_cred(); 2652 const struct cred *cred = current_cred();
2638 2653
2639 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2654 return dentry_has_perm(cred, dentry, FILE__READ);
2640} 2655}
2641 2656
2642static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags) 2657static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags)
@@ -2653,8 +2668,8 @@ static int selinux_inode_permission(struct inode *inode, int mask, unsigned flag
2653 if (!mask) 2668 if (!mask)
2654 return 0; 2669 return 0;
2655 2670
2656 COMMON_AUDIT_DATA_INIT(&ad, FS); 2671 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2657 ad.u.fs.inode = inode; 2672 ad.u.inode = inode;
2658 2673
2659 if (from_access) 2674 if (from_access)
2660 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS; 2675 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
@@ -2679,16 +2694,20 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2679 2694
2680 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | 2695 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
2681 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) 2696 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
2682 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2697 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2683 2698
2684 return dentry_has_perm(cred, NULL, dentry, FILE__WRITE); 2699 return dentry_has_perm(cred, dentry, FILE__WRITE);
2685} 2700}
2686 2701
2687static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 2702static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2688{ 2703{
2689 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;
2690 2709
2691 return dentry_has_perm(cred, mnt, dentry, FILE__GETATTR); 2710 return path_has_perm(cred, &path, FILE__GETATTR);
2692} 2711}
2693 2712
2694static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) 2713static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
@@ -2709,7 +2728,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
2709 2728
2710 /* Not an attribute we recognize, so just check the 2729 /* Not an attribute we recognize, so just check the
2711 ordinary setattr permission. */ 2730 ordinary setattr permission. */
2712 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2731 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2713} 2732}
2714 2733
2715static int selinux_inode_setxattr(struct dentry *dentry, const char *name, 2734static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
@@ -2732,8 +2751,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2732 if (!inode_owner_or_capable(inode)) 2751 if (!inode_owner_or_capable(inode))
2733 return -EPERM; 2752 return -EPERM;
2734 2753
2735 COMMON_AUDIT_DATA_INIT(&ad, FS); 2754 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2736 ad.u.fs.path.dentry = dentry; 2755 ad.u.dentry = dentry;
2737 2756
2738 rc = avc_has_perm(sid, isec->sid, isec->sclass, 2757 rc = avc_has_perm(sid, isec->sid, isec->sclass,
2739 FILE__RELABELFROM, &ad); 2758 FILE__RELABELFROM, &ad);
@@ -2796,14 +2815,14 @@ static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
2796{ 2815{
2797 const struct cred *cred = current_cred(); 2816 const struct cred *cred = current_cred();
2798 2817
2799 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2818 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2800} 2819}
2801 2820
2802static int selinux_inode_listxattr(struct dentry *dentry) 2821static int selinux_inode_listxattr(struct dentry *dentry)
2803{ 2822{
2804 const struct cred *cred = current_cred(); 2823 const struct cred *cred = current_cred();
2805 2824
2806 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2825 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2807} 2826}
2808 2827
2809static int selinux_inode_removexattr(struct dentry *dentry, const char *name) 2828static int selinux_inode_removexattr(struct dentry *dentry, const char *name)