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.c119
1 files changed, 71 insertions, 48 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index f9c3764e4859..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,11 +1444,15 @@ 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);
1449 if (audit == SECURITY_CAP_AUDIT) 1451 if (audit == SECURITY_CAP_AUDIT) {
1450 avc_audit(sid, sid, sclass, av, &avd, rc, &ad); 1452 int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0);
1453 if (rc2)
1454 return rc2;
1455 }
1451 return rc; 1456 return rc;
1452} 1457}
1453 1458
@@ -1467,7 +1472,8 @@ static int task_has_system(struct task_struct *tsk,
1467static int inode_has_perm(const struct cred *cred, 1472static int inode_has_perm(const struct cred *cred,
1468 struct inode *inode, 1473 struct inode *inode,
1469 u32 perms, 1474 u32 perms,
1470 struct common_audit_data *adp) 1475 struct common_audit_data *adp,
1476 unsigned flags)
1471{ 1477{
1472 struct inode_security_struct *isec; 1478 struct inode_security_struct *isec;
1473 struct common_audit_data ad; 1479 struct common_audit_data ad;
@@ -1483,28 +1489,41 @@ static int inode_has_perm(const struct cred *cred,
1483 1489
1484 if (!adp) { 1490 if (!adp) {
1485 adp = &ad; 1491 adp = &ad;
1486 COMMON_AUDIT_DATA_INIT(&ad, FS); 1492 COMMON_AUDIT_DATA_INIT(&ad, INODE);
1487 ad.u.fs.inode = inode; 1493 ad.u.inode = inode;
1488 } 1494 }
1489 1495
1490 return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp); 1496 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
1491} 1497}
1492 1498
1493/* Same as inode_has_perm, but pass explicit audit data containing 1499/* Same as inode_has_perm, but pass explicit audit data containing
1494 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
1495 pathname if needed. */ 1501 pathname if needed. */
1496static inline int dentry_has_perm(const struct cred *cred, 1502static inline int dentry_has_perm(const struct cred *cred,
1497 struct vfsmount *mnt,
1498 struct dentry *dentry, 1503 struct dentry *dentry,
1499 u32 av) 1504 u32 av)
1500{ 1505{
1501 struct inode *inode = dentry->d_inode; 1506 struct inode *inode = dentry->d_inode;
1502 struct common_audit_data ad; 1507 struct common_audit_data ad;
1503 1508
1504 COMMON_AUDIT_DATA_INIT(&ad, FS); 1509 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1505 ad.u.fs.path.mnt = mnt; 1510 ad.u.dentry = dentry;
1506 ad.u.fs.path.dentry = dentry; 1511 return inode_has_perm(cred, inode, av, &ad, 0);
1507 return inode_has_perm(cred, inode, av, &ad); 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;
1526 return inode_has_perm(cred, inode, av, &ad, 0);
1508} 1527}
1509 1528
1510/* Check whether a task can use an open file descriptor to 1529/* Check whether a task can use an open file descriptor to
@@ -1525,8 +1544,8 @@ static int file_has_perm(const struct cred *cred,
1525 u32 sid = cred_sid(cred); 1544 u32 sid = cred_sid(cred);
1526 int rc; 1545 int rc;
1527 1546
1528 COMMON_AUDIT_DATA_INIT(&ad, FS); 1547 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1529 ad.u.fs.path = file->f_path; 1548 ad.u.path = file->f_path;
1530 1549
1531 if (sid != fsec->sid) { 1550 if (sid != fsec->sid) {
1532 rc = avc_has_perm(sid, fsec->sid, 1551 rc = avc_has_perm(sid, fsec->sid,
@@ -1540,7 +1559,7 @@ static int file_has_perm(const struct cred *cred,
1540 /* av is zero if only checking access to the descriptor. */ 1559 /* av is zero if only checking access to the descriptor. */
1541 rc = 0; 1560 rc = 0;
1542 if (av) 1561 if (av)
1543 rc = inode_has_perm(cred, inode, av, &ad); 1562 rc = inode_has_perm(cred, inode, av, &ad, 0);
1544 1563
1545out: 1564out:
1546 return rc; 1565 return rc;
@@ -1564,8 +1583,8 @@ static int may_create(struct inode *dir,
1564 sid = tsec->sid; 1583 sid = tsec->sid;
1565 newsid = tsec->create_sid; 1584 newsid = tsec->create_sid;
1566 1585
1567 COMMON_AUDIT_DATA_INIT(&ad, FS); 1586 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1568 ad.u.fs.path.dentry = dentry; 1587 ad.u.dentry = dentry;
1569 1588
1570 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, 1589 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
1571 DIR__ADD_NAME | DIR__SEARCH, 1590 DIR__ADD_NAME | DIR__SEARCH,
@@ -1574,7 +1593,8 @@ static int may_create(struct inode *dir,
1574 return rc; 1593 return rc;
1575 1594
1576 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 1595 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
1577 rc = security_transition_sid(sid, dsec->sid, tclass, NULL, &newsid); 1596 rc = security_transition_sid(sid, dsec->sid, tclass,
1597 &dentry->d_name, &newsid);
1578 if (rc) 1598 if (rc)
1579 return rc; 1599 return rc;
1580 } 1600 }
@@ -1616,8 +1636,8 @@ static int may_link(struct inode *dir,
1616 dsec = dir->i_security; 1636 dsec = dir->i_security;
1617 isec = dentry->d_inode->i_security; 1637 isec = dentry->d_inode->i_security;
1618 1638
1619 COMMON_AUDIT_DATA_INIT(&ad, FS); 1639 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1620 ad.u.fs.path.dentry = dentry; 1640 ad.u.dentry = dentry;
1621 1641
1622 av = DIR__SEARCH; 1642 av = DIR__SEARCH;
1623 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); 1643 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
@@ -1662,9 +1682,9 @@ static inline int may_rename(struct inode *old_dir,
1662 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); 1682 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
1663 new_dsec = new_dir->i_security; 1683 new_dsec = new_dir->i_security;
1664 1684
1665 COMMON_AUDIT_DATA_INIT(&ad, FS); 1685 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1666 1686
1667 ad.u.fs.path.dentry = old_dentry; 1687 ad.u.dentry = old_dentry;
1668 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, 1688 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
1669 DIR__REMOVE_NAME | DIR__SEARCH, &ad); 1689 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1670 if (rc) 1690 if (rc)
@@ -1680,7 +1700,7 @@ static inline int may_rename(struct inode *old_dir,
1680 return rc; 1700 return rc;
1681 } 1701 }
1682 1702
1683 ad.u.fs.path.dentry = new_dentry; 1703 ad.u.dentry = new_dentry;
1684 av = DIR__ADD_NAME | DIR__SEARCH; 1704 av = DIR__ADD_NAME | DIR__SEARCH;
1685 if (new_dentry->d_inode) 1705 if (new_dentry->d_inode)
1686 av |= DIR__REMOVE_NAME; 1706 av |= DIR__REMOVE_NAME;
@@ -1890,7 +1910,7 @@ static int selinux_quota_on(struct dentry *dentry)
1890{ 1910{
1891 const struct cred *cred = current_cred(); 1911 const struct cred *cred = current_cred();
1892 1912
1893 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); 1913 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
1894} 1914}
1895 1915
1896static int selinux_syslog(int type) 1916static int selinux_syslog(int type)
@@ -1987,8 +2007,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
1987 return rc; 2007 return rc;
1988 } 2008 }
1989 2009
1990 COMMON_AUDIT_DATA_INIT(&ad, FS); 2010 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1991 ad.u.fs.path = bprm->file->f_path; 2011 ad.u.path = bprm->file->f_path;
1992 2012
1993 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) 2013 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
1994 new_tsec->sid = old_tsec->sid; 2014 new_tsec->sid = old_tsec->sid;
@@ -2103,7 +2123,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2103 file = file_priv->file; 2123 file = file_priv->file;
2104 inode = file->f_path.dentry->d_inode; 2124 inode = file->f_path.dentry->d_inode;
2105 if (inode_has_perm(cred, inode, 2125 if (inode_has_perm(cred, inode,
2106 FILE__READ | FILE__WRITE, NULL)) { 2126 FILE__READ | FILE__WRITE, NULL, 0)) {
2107 drop_tty = 1; 2127 drop_tty = 1;
2108 } 2128 }
2109 } 2129 }
@@ -2116,7 +2136,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2116 2136
2117 /* Revalidate access to inherited open files. */ 2137 /* Revalidate access to inherited open files. */
2118 2138
2119 COMMON_AUDIT_DATA_INIT(&ad, FS); 2139 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2120 2140
2121 spin_lock(&files->file_lock); 2141 spin_lock(&files->file_lock);
2122 for (;;) { 2142 for (;;) {
@@ -2464,8 +2484,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
2464 if (flags & MS_KERNMOUNT) 2484 if (flags & MS_KERNMOUNT)
2465 return 0; 2485 return 0;
2466 2486
2467 COMMON_AUDIT_DATA_INIT(&ad, FS); 2487 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2468 ad.u.fs.path.dentry = sb->s_root; 2488 ad.u.dentry = sb->s_root;
2469 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); 2489 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
2470} 2490}
2471 2491
@@ -2474,8 +2494,8 @@ static int selinux_sb_statfs(struct dentry *dentry)
2474 const struct cred *cred = current_cred(); 2494 const struct cred *cred = current_cred();
2475 struct common_audit_data ad; 2495 struct common_audit_data ad;
2476 2496
2477 COMMON_AUDIT_DATA_INIT(&ad, FS); 2497 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2478 ad.u.fs.path.dentry = dentry->d_sb->s_root; 2498 ad.u.dentry = dentry->d_sb->s_root;
2479 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); 2499 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
2480} 2500}
2481 2501
@@ -2491,8 +2511,7 @@ static int selinux_mount(char *dev_name,
2491 return superblock_has_perm(cred, path->mnt->mnt_sb, 2511 return superblock_has_perm(cred, path->mnt->mnt_sb,
2492 FILESYSTEM__REMOUNT, NULL); 2512 FILESYSTEM__REMOUNT, NULL);
2493 else 2513 else
2494 return dentry_has_perm(cred, path->mnt, path->dentry, 2514 return path_has_perm(cred, path, FILE__MOUNTON);
2495 FILE__MOUNTON);
2496} 2515}
2497 2516
2498static int selinux_umount(struct vfsmount *mnt, int flags) 2517static int selinux_umount(struct vfsmount *mnt, int flags)
@@ -2625,17 +2644,17 @@ static int selinux_inode_readlink(struct dentry *dentry)
2625{ 2644{
2626 const struct cred *cred = current_cred(); 2645 const struct cred *cred = current_cred();
2627 2646
2628 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2647 return dentry_has_perm(cred, dentry, FILE__READ);
2629} 2648}
2630 2649
2631static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) 2650static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
2632{ 2651{
2633 const struct cred *cred = current_cred(); 2652 const struct cred *cred = current_cred();
2634 2653
2635 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2654 return dentry_has_perm(cred, dentry, FILE__READ);
2636} 2655}
2637 2656
2638static int selinux_inode_permission(struct inode *inode, int mask) 2657static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags)
2639{ 2658{
2640 const struct cred *cred = current_cred(); 2659 const struct cred *cred = current_cred();
2641 struct common_audit_data ad; 2660 struct common_audit_data ad;
@@ -2649,15 +2668,15 @@ static int selinux_inode_permission(struct inode *inode, int mask)
2649 if (!mask) 2668 if (!mask)
2650 return 0; 2669 return 0;
2651 2670
2652 COMMON_AUDIT_DATA_INIT(&ad, FS); 2671 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2653 ad.u.fs.inode = inode; 2672 ad.u.inode = inode;
2654 2673
2655 if (from_access) 2674 if (from_access)
2656 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS; 2675 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
2657 2676
2658 perms = file_mask_to_av(inode->i_mode, mask); 2677 perms = file_mask_to_av(inode->i_mode, mask);
2659 2678
2660 return inode_has_perm(cred, inode, perms, &ad); 2679 return inode_has_perm(cred, inode, perms, &ad, flags);
2661} 2680}
2662 2681
2663static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2682static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
@@ -2675,16 +2694,20 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2675 2694
2676 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | 2695 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
2677 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) 2696 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
2678 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2697 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2679 2698
2680 return dentry_has_perm(cred, NULL, dentry, FILE__WRITE); 2699 return dentry_has_perm(cred, dentry, FILE__WRITE);
2681} 2700}
2682 2701
2683static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 2702static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2684{ 2703{
2685 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;
2686 2709
2687 return dentry_has_perm(cred, mnt, dentry, FILE__GETATTR); 2710 return path_has_perm(cred, &path, FILE__GETATTR);
2688} 2711}
2689 2712
2690static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) 2713static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
@@ -2705,7 +2728,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
2705 2728
2706 /* Not an attribute we recognize, so just check the 2729 /* Not an attribute we recognize, so just check the
2707 ordinary setattr permission. */ 2730 ordinary setattr permission. */
2708 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2731 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2709} 2732}
2710 2733
2711static int selinux_inode_setxattr(struct dentry *dentry, const char *name, 2734static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
@@ -2728,8 +2751,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2728 if (!inode_owner_or_capable(inode)) 2751 if (!inode_owner_or_capable(inode))
2729 return -EPERM; 2752 return -EPERM;
2730 2753
2731 COMMON_AUDIT_DATA_INIT(&ad, FS); 2754 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2732 ad.u.fs.path.dentry = dentry; 2755 ad.u.dentry = dentry;
2733 2756
2734 rc = avc_has_perm(sid, isec->sid, isec->sclass, 2757 rc = avc_has_perm(sid, isec->sid, isec->sclass,
2735 FILE__RELABELFROM, &ad); 2758 FILE__RELABELFROM, &ad);
@@ -2792,14 +2815,14 @@ static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
2792{ 2815{
2793 const struct cred *cred = current_cred(); 2816 const struct cred *cred = current_cred();
2794 2817
2795 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2818 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2796} 2819}
2797 2820
2798static int selinux_inode_listxattr(struct dentry *dentry) 2821static int selinux_inode_listxattr(struct dentry *dentry)
2799{ 2822{
2800 const struct cred *cred = current_cred(); 2823 const struct cred *cred = current_cred();
2801 2824
2802 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2825 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2803} 2826}
2804 2827
2805static int selinux_inode_removexattr(struct dentry *dentry, const char *name) 2828static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
@@ -3205,7 +3228,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
3205 * new inode label or new policy. 3228 * new inode label or new policy.
3206 * This check is not redundant - do not remove. 3229 * This check is not redundant - do not remove.
3207 */ 3230 */
3208 return inode_has_perm(cred, inode, open_file_to_av(file), NULL); 3231 return inode_has_perm(cred, inode, open_file_to_av(file), NULL, 0);
3209} 3232}
3210 3233
3211/* task security operations */ 3234/* task security operations */