diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 268 |
1 files changed, 127 insertions, 141 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d85b793c9321..fa2341b68331 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1420,16 +1420,13 @@ static int cred_has_capability(const struct cred *cred, | |||
1420 | int cap, int audit) | 1420 | int cap, int audit) |
1421 | { | 1421 | { |
1422 | struct common_audit_data ad; | 1422 | struct common_audit_data ad; |
1423 | struct selinux_audit_data sad = {0,}; | ||
1424 | struct av_decision avd; | 1423 | struct av_decision avd; |
1425 | u16 sclass; | 1424 | u16 sclass; |
1426 | u32 sid = cred_sid(cred); | 1425 | u32 sid = cred_sid(cred); |
1427 | u32 av = CAP_TO_MASK(cap); | 1426 | u32 av = CAP_TO_MASK(cap); |
1428 | int rc; | 1427 | int rc; |
1429 | 1428 | ||
1430 | COMMON_AUDIT_DATA_INIT(&ad, CAP); | 1429 | ad.type = LSM_AUDIT_DATA_CAP; |
1431 | ad.selinux_audit_data = &sad; | ||
1432 | ad.tsk = current; | ||
1433 | ad.u.cap = cap; | 1430 | ad.u.cap = cap; |
1434 | 1431 | ||
1435 | switch (CAP_TO_INDEX(cap)) { | 1432 | switch (CAP_TO_INDEX(cap)) { |
@@ -1488,20 +1485,6 @@ static int inode_has_perm(const struct cred *cred, | |||
1488 | return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); | 1485 | return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); |
1489 | } | 1486 | } |
1490 | 1487 | ||
1491 | static int inode_has_perm_noadp(const struct cred *cred, | ||
1492 | struct inode *inode, | ||
1493 | u32 perms, | ||
1494 | unsigned flags) | ||
1495 | { | ||
1496 | struct common_audit_data ad; | ||
1497 | struct selinux_audit_data sad = {0,}; | ||
1498 | |||
1499 | COMMON_AUDIT_DATA_INIT(&ad, INODE); | ||
1500 | ad.u.inode = inode; | ||
1501 | ad.selinux_audit_data = &sad; | ||
1502 | return inode_has_perm(cred, inode, perms, &ad, flags); | ||
1503 | } | ||
1504 | |||
1505 | /* Same as inode_has_perm, but pass explicit audit data containing | 1488 | /* Same as inode_has_perm, but pass explicit audit data containing |
1506 | the dentry to help the auditing code to more easily generate the | 1489 | the dentry to help the auditing code to more easily generate the |
1507 | pathname if needed. */ | 1490 | pathname if needed. */ |
@@ -1511,11 +1494,9 @@ static inline int dentry_has_perm(const struct cred *cred, | |||
1511 | { | 1494 | { |
1512 | struct inode *inode = dentry->d_inode; | 1495 | struct inode *inode = dentry->d_inode; |
1513 | struct common_audit_data ad; | 1496 | struct common_audit_data ad; |
1514 | struct selinux_audit_data sad = {0,}; | ||
1515 | 1497 | ||
1516 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 1498 | ad.type = LSM_AUDIT_DATA_DENTRY; |
1517 | ad.u.dentry = dentry; | 1499 | ad.u.dentry = dentry; |
1518 | ad.selinux_audit_data = &sad; | ||
1519 | return inode_has_perm(cred, inode, av, &ad, 0); | 1500 | return inode_has_perm(cred, inode, av, &ad, 0); |
1520 | } | 1501 | } |
1521 | 1502 | ||
@@ -1528,11 +1509,9 @@ static inline int path_has_perm(const struct cred *cred, | |||
1528 | { | 1509 | { |
1529 | struct inode *inode = path->dentry->d_inode; | 1510 | struct inode *inode = path->dentry->d_inode; |
1530 | struct common_audit_data ad; | 1511 | struct common_audit_data ad; |
1531 | struct selinux_audit_data sad = {0,}; | ||
1532 | 1512 | ||
1533 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 1513 | ad.type = LSM_AUDIT_DATA_PATH; |
1534 | ad.u.path = *path; | 1514 | ad.u.path = *path; |
1535 | ad.selinux_audit_data = &sad; | ||
1536 | return inode_has_perm(cred, inode, av, &ad, 0); | 1515 | return inode_has_perm(cred, inode, av, &ad, 0); |
1537 | } | 1516 | } |
1538 | 1517 | ||
@@ -1551,13 +1530,11 @@ static int file_has_perm(const struct cred *cred, | |||
1551 | struct file_security_struct *fsec = file->f_security; | 1530 | struct file_security_struct *fsec = file->f_security; |
1552 | struct inode *inode = file->f_path.dentry->d_inode; | 1531 | struct inode *inode = file->f_path.dentry->d_inode; |
1553 | struct common_audit_data ad; | 1532 | struct common_audit_data ad; |
1554 | struct selinux_audit_data sad = {0,}; | ||
1555 | u32 sid = cred_sid(cred); | 1533 | u32 sid = cred_sid(cred); |
1556 | int rc; | 1534 | int rc; |
1557 | 1535 | ||
1558 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 1536 | ad.type = LSM_AUDIT_DATA_PATH; |
1559 | ad.u.path = file->f_path; | 1537 | ad.u.path = file->f_path; |
1560 | ad.selinux_audit_data = &sad; | ||
1561 | 1538 | ||
1562 | if (sid != fsec->sid) { | 1539 | if (sid != fsec->sid) { |
1563 | rc = avc_has_perm(sid, fsec->sid, | 1540 | rc = avc_has_perm(sid, fsec->sid, |
@@ -1587,7 +1564,6 @@ static int may_create(struct inode *dir, | |||
1587 | struct superblock_security_struct *sbsec; | 1564 | struct superblock_security_struct *sbsec; |
1588 | u32 sid, newsid; | 1565 | u32 sid, newsid; |
1589 | struct common_audit_data ad; | 1566 | struct common_audit_data ad; |
1590 | struct selinux_audit_data sad = {0,}; | ||
1591 | int rc; | 1567 | int rc; |
1592 | 1568 | ||
1593 | dsec = dir->i_security; | 1569 | dsec = dir->i_security; |
@@ -1596,9 +1572,8 @@ static int may_create(struct inode *dir, | |||
1596 | sid = tsec->sid; | 1572 | sid = tsec->sid; |
1597 | newsid = tsec->create_sid; | 1573 | newsid = tsec->create_sid; |
1598 | 1574 | ||
1599 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 1575 | ad.type = LSM_AUDIT_DATA_DENTRY; |
1600 | ad.u.dentry = dentry; | 1576 | ad.u.dentry = dentry; |
1601 | ad.selinux_audit_data = &sad; | ||
1602 | 1577 | ||
1603 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, | 1578 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, |
1604 | DIR__ADD_NAME | DIR__SEARCH, | 1579 | DIR__ADD_NAME | DIR__SEARCH, |
@@ -1643,7 +1618,6 @@ static int may_link(struct inode *dir, | |||
1643 | { | 1618 | { |
1644 | struct inode_security_struct *dsec, *isec; | 1619 | struct inode_security_struct *dsec, *isec; |
1645 | struct common_audit_data ad; | 1620 | struct common_audit_data ad; |
1646 | struct selinux_audit_data sad = {0,}; | ||
1647 | u32 sid = current_sid(); | 1621 | u32 sid = current_sid(); |
1648 | u32 av; | 1622 | u32 av; |
1649 | int rc; | 1623 | int rc; |
@@ -1651,9 +1625,8 @@ static int may_link(struct inode *dir, | |||
1651 | dsec = dir->i_security; | 1625 | dsec = dir->i_security; |
1652 | isec = dentry->d_inode->i_security; | 1626 | isec = dentry->d_inode->i_security; |
1653 | 1627 | ||
1654 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 1628 | ad.type = LSM_AUDIT_DATA_DENTRY; |
1655 | ad.u.dentry = dentry; | 1629 | ad.u.dentry = dentry; |
1656 | ad.selinux_audit_data = &sad; | ||
1657 | 1630 | ||
1658 | av = DIR__SEARCH; | 1631 | av = DIR__SEARCH; |
1659 | av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); | 1632 | av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); |
@@ -1688,7 +1661,6 @@ static inline int may_rename(struct inode *old_dir, | |||
1688 | { | 1661 | { |
1689 | struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; | 1662 | struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; |
1690 | struct common_audit_data ad; | 1663 | struct common_audit_data ad; |
1691 | struct selinux_audit_data sad = {0,}; | ||
1692 | u32 sid = current_sid(); | 1664 | u32 sid = current_sid(); |
1693 | u32 av; | 1665 | u32 av; |
1694 | int old_is_dir, new_is_dir; | 1666 | int old_is_dir, new_is_dir; |
@@ -1699,8 +1671,7 @@ static inline int may_rename(struct inode *old_dir, | |||
1699 | old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); | 1671 | old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); |
1700 | new_dsec = new_dir->i_security; | 1672 | new_dsec = new_dir->i_security; |
1701 | 1673 | ||
1702 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 1674 | ad.type = LSM_AUDIT_DATA_DENTRY; |
1703 | ad.selinux_audit_data = &sad; | ||
1704 | 1675 | ||
1705 | ad.u.dentry = old_dentry; | 1676 | ad.u.dentry = old_dentry; |
1706 | rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, | 1677 | rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, |
@@ -1986,7 +1957,6 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
1986 | struct task_security_struct *new_tsec; | 1957 | struct task_security_struct *new_tsec; |
1987 | struct inode_security_struct *isec; | 1958 | struct inode_security_struct *isec; |
1988 | struct common_audit_data ad; | 1959 | struct common_audit_data ad; |
1989 | struct selinux_audit_data sad = {0,}; | ||
1990 | struct inode *inode = bprm->file->f_path.dentry->d_inode; | 1960 | struct inode *inode = bprm->file->f_path.dentry->d_inode; |
1991 | int rc; | 1961 | int rc; |
1992 | 1962 | ||
@@ -2016,6 +1986,13 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2016 | new_tsec->sid = old_tsec->exec_sid; | 1986 | new_tsec->sid = old_tsec->exec_sid; |
2017 | /* Reset exec SID on execve. */ | 1987 | /* Reset exec SID on execve. */ |
2018 | new_tsec->exec_sid = 0; | 1988 | new_tsec->exec_sid = 0; |
1989 | |||
1990 | /* | ||
1991 | * Minimize confusion: if no_new_privs and a transition is | ||
1992 | * explicitly requested, then fail the exec. | ||
1993 | */ | ||
1994 | if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) | ||
1995 | return -EPERM; | ||
2019 | } else { | 1996 | } else { |
2020 | /* Check for a default transition on this program. */ | 1997 | /* Check for a default transition on this program. */ |
2021 | rc = security_transition_sid(old_tsec->sid, isec->sid, | 1998 | rc = security_transition_sid(old_tsec->sid, isec->sid, |
@@ -2025,11 +2002,11 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2025 | return rc; | 2002 | return rc; |
2026 | } | 2003 | } |
2027 | 2004 | ||
2028 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 2005 | ad.type = LSM_AUDIT_DATA_PATH; |
2029 | ad.selinux_audit_data = &sad; | ||
2030 | ad.u.path = bprm->file->f_path; | 2006 | ad.u.path = bprm->file->f_path; |
2031 | 2007 | ||
2032 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) | 2008 | if ((bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) || |
2009 | (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) | ||
2033 | new_tsec->sid = old_tsec->sid; | 2010 | new_tsec->sid = old_tsec->sid; |
2034 | 2011 | ||
2035 | if (new_tsec->sid == old_tsec->sid) { | 2012 | if (new_tsec->sid == old_tsec->sid) { |
@@ -2115,8 +2092,6 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm) | |||
2115 | static inline void flush_unauthorized_files(const struct cred *cred, | 2092 | static inline void flush_unauthorized_files(const struct cred *cred, |
2116 | struct files_struct *files) | 2093 | struct files_struct *files) |
2117 | { | 2094 | { |
2118 | struct common_audit_data ad; | ||
2119 | struct selinux_audit_data sad = {0,}; | ||
2120 | struct file *file, *devnull = NULL; | 2095 | struct file *file, *devnull = NULL; |
2121 | struct tty_struct *tty; | 2096 | struct tty_struct *tty; |
2122 | struct fdtable *fdt; | 2097 | struct fdtable *fdt; |
@@ -2128,21 +2103,17 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
2128 | spin_lock(&tty_files_lock); | 2103 | spin_lock(&tty_files_lock); |
2129 | if (!list_empty(&tty->tty_files)) { | 2104 | if (!list_empty(&tty->tty_files)) { |
2130 | struct tty_file_private *file_priv; | 2105 | struct tty_file_private *file_priv; |
2131 | struct inode *inode; | ||
2132 | 2106 | ||
2133 | /* Revalidate access to controlling tty. | 2107 | /* Revalidate access to controlling tty. |
2134 | Use inode_has_perm on the tty inode directly rather | 2108 | Use path_has_perm on the tty path directly rather |
2135 | than using file_has_perm, as this particular open | 2109 | than using file_has_perm, as this particular open |
2136 | file may belong to another process and we are only | 2110 | file may belong to another process and we are only |
2137 | interested in the inode-based check here. */ | 2111 | interested in the inode-based check here. */ |
2138 | file_priv = list_first_entry(&tty->tty_files, | 2112 | file_priv = list_first_entry(&tty->tty_files, |
2139 | struct tty_file_private, list); | 2113 | struct tty_file_private, list); |
2140 | file = file_priv->file; | 2114 | file = file_priv->file; |
2141 | inode = file->f_path.dentry->d_inode; | 2115 | if (path_has_perm(cred, &file->f_path, FILE__READ | FILE__WRITE)) |
2142 | if (inode_has_perm_noadp(cred, inode, | ||
2143 | FILE__READ | FILE__WRITE, 0)) { | ||
2144 | drop_tty = 1; | 2116 | drop_tty = 1; |
2145 | } | ||
2146 | } | 2117 | } |
2147 | spin_unlock(&tty_files_lock); | 2118 | spin_unlock(&tty_files_lock); |
2148 | tty_kref_put(tty); | 2119 | tty_kref_put(tty); |
@@ -2152,10 +2123,6 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
2152 | no_tty(); | 2123 | no_tty(); |
2153 | 2124 | ||
2154 | /* Revalidate access to inherited open files. */ | 2125 | /* Revalidate access to inherited open files. */ |
2155 | |||
2156 | COMMON_AUDIT_DATA_INIT(&ad, INODE); | ||
2157 | ad.selinux_audit_data = &sad; | ||
2158 | |||
2159 | spin_lock(&files->file_lock); | 2126 | spin_lock(&files->file_lock); |
2160 | for (;;) { | 2127 | for (;;) { |
2161 | unsigned long set, i; | 2128 | unsigned long set, i; |
@@ -2492,7 +2459,6 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
2492 | { | 2459 | { |
2493 | const struct cred *cred = current_cred(); | 2460 | const struct cred *cred = current_cred(); |
2494 | struct common_audit_data ad; | 2461 | struct common_audit_data ad; |
2495 | struct selinux_audit_data sad = {0,}; | ||
2496 | int rc; | 2462 | int rc; |
2497 | 2463 | ||
2498 | rc = superblock_doinit(sb, data); | 2464 | rc = superblock_doinit(sb, data); |
@@ -2503,8 +2469,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
2503 | if (flags & MS_KERNMOUNT) | 2469 | if (flags & MS_KERNMOUNT) |
2504 | return 0; | 2470 | return 0; |
2505 | 2471 | ||
2506 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 2472 | ad.type = LSM_AUDIT_DATA_DENTRY; |
2507 | ad.selinux_audit_data = &sad; | ||
2508 | ad.u.dentry = sb->s_root; | 2473 | ad.u.dentry = sb->s_root; |
2509 | return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); | 2474 | return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); |
2510 | } | 2475 | } |
@@ -2513,10 +2478,8 @@ static int selinux_sb_statfs(struct dentry *dentry) | |||
2513 | { | 2478 | { |
2514 | const struct cred *cred = current_cred(); | 2479 | const struct cred *cred = current_cred(); |
2515 | struct common_audit_data ad; | 2480 | struct common_audit_data ad; |
2516 | struct selinux_audit_data sad = {0,}; | ||
2517 | 2481 | ||
2518 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 2482 | ad.type = LSM_AUDIT_DATA_DENTRY; |
2519 | ad.selinux_audit_data = &sad; | ||
2520 | ad.u.dentry = dentry->d_sb->s_root; | 2483 | ad.u.dentry = dentry->d_sb->s_root; |
2521 | return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); | 2484 | return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); |
2522 | } | 2485 | } |
@@ -2676,14 +2639,35 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na | |||
2676 | return dentry_has_perm(cred, dentry, FILE__READ); | 2639 | return dentry_has_perm(cred, dentry, FILE__READ); |
2677 | } | 2640 | } |
2678 | 2641 | ||
2642 | static noinline int audit_inode_permission(struct inode *inode, | ||
2643 | u32 perms, u32 audited, u32 denied, | ||
2644 | unsigned flags) | ||
2645 | { | ||
2646 | struct common_audit_data ad; | ||
2647 | struct inode_security_struct *isec = inode->i_security; | ||
2648 | int rc; | ||
2649 | |||
2650 | ad.type = LSM_AUDIT_DATA_INODE; | ||
2651 | ad.u.inode = inode; | ||
2652 | |||
2653 | rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms, | ||
2654 | audited, denied, &ad, flags); | ||
2655 | if (rc) | ||
2656 | return rc; | ||
2657 | return 0; | ||
2658 | } | ||
2659 | |||
2679 | static int selinux_inode_permission(struct inode *inode, int mask) | 2660 | static int selinux_inode_permission(struct inode *inode, int mask) |
2680 | { | 2661 | { |
2681 | const struct cred *cred = current_cred(); | 2662 | const struct cred *cred = current_cred(); |
2682 | struct common_audit_data ad; | ||
2683 | struct selinux_audit_data sad = {0,}; | ||
2684 | u32 perms; | 2663 | u32 perms; |
2685 | bool from_access; | 2664 | bool from_access; |
2686 | unsigned flags = mask & MAY_NOT_BLOCK; | 2665 | unsigned flags = mask & MAY_NOT_BLOCK; |
2666 | struct inode_security_struct *isec; | ||
2667 | u32 sid; | ||
2668 | struct av_decision avd; | ||
2669 | int rc, rc2; | ||
2670 | u32 audited, denied; | ||
2687 | 2671 | ||
2688 | from_access = mask & MAY_ACCESS; | 2672 | from_access = mask & MAY_ACCESS; |
2689 | mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND); | 2673 | mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND); |
@@ -2692,22 +2676,34 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
2692 | if (!mask) | 2676 | if (!mask) |
2693 | return 0; | 2677 | return 0; |
2694 | 2678 | ||
2695 | COMMON_AUDIT_DATA_INIT(&ad, INODE); | 2679 | validate_creds(cred); |
2696 | ad.selinux_audit_data = &sad; | ||
2697 | ad.u.inode = inode; | ||
2698 | 2680 | ||
2699 | if (from_access) | 2681 | if (unlikely(IS_PRIVATE(inode))) |
2700 | ad.selinux_audit_data->auditdeny |= FILE__AUDIT_ACCESS; | 2682 | return 0; |
2701 | 2683 | ||
2702 | perms = file_mask_to_av(inode->i_mode, mask); | 2684 | perms = file_mask_to_av(inode->i_mode, mask); |
2703 | 2685 | ||
2704 | return inode_has_perm(cred, inode, perms, &ad, flags); | 2686 | sid = cred_sid(cred); |
2687 | isec = inode->i_security; | ||
2688 | |||
2689 | rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd); | ||
2690 | audited = avc_audit_required(perms, &avd, rc, | ||
2691 | from_access ? FILE__AUDIT_ACCESS : 0, | ||
2692 | &denied); | ||
2693 | if (likely(!audited)) | ||
2694 | return rc; | ||
2695 | |||
2696 | rc2 = audit_inode_permission(inode, perms, audited, denied, flags); | ||
2697 | if (rc2) | ||
2698 | return rc2; | ||
2699 | return rc; | ||
2705 | } | 2700 | } |
2706 | 2701 | ||
2707 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | 2702 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) |
2708 | { | 2703 | { |
2709 | const struct cred *cred = current_cred(); | 2704 | const struct cred *cred = current_cred(); |
2710 | unsigned int ia_valid = iattr->ia_valid; | 2705 | unsigned int ia_valid = iattr->ia_valid; |
2706 | __u32 av = FILE__WRITE; | ||
2711 | 2707 | ||
2712 | /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */ | 2708 | /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */ |
2713 | if (ia_valid & ATTR_FORCE) { | 2709 | if (ia_valid & ATTR_FORCE) { |
@@ -2721,7 +2717,10 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
2721 | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) | 2717 | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) |
2722 | return dentry_has_perm(cred, dentry, FILE__SETATTR); | 2718 | return dentry_has_perm(cred, dentry, FILE__SETATTR); |
2723 | 2719 | ||
2724 | return dentry_has_perm(cred, dentry, FILE__WRITE); | 2720 | if (ia_valid & ATTR_SIZE) |
2721 | av |= FILE__OPEN; | ||
2722 | |||
2723 | return dentry_has_perm(cred, dentry, av); | ||
2725 | } | 2724 | } |
2726 | 2725 | ||
2727 | static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | 2726 | static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) |
@@ -2763,7 +2762,6 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2763 | struct inode_security_struct *isec = inode->i_security; | 2762 | struct inode_security_struct *isec = inode->i_security; |
2764 | struct superblock_security_struct *sbsec; | 2763 | struct superblock_security_struct *sbsec; |
2765 | struct common_audit_data ad; | 2764 | struct common_audit_data ad; |
2766 | struct selinux_audit_data sad = {0,}; | ||
2767 | u32 newsid, sid = current_sid(); | 2765 | u32 newsid, sid = current_sid(); |
2768 | int rc = 0; | 2766 | int rc = 0; |
2769 | 2767 | ||
@@ -2777,8 +2775,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2777 | if (!inode_owner_or_capable(inode)) | 2775 | if (!inode_owner_or_capable(inode)) |
2778 | return -EPERM; | 2776 | return -EPERM; |
2779 | 2777 | ||
2780 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); | 2778 | ad.type = LSM_AUDIT_DATA_DENTRY; |
2781 | ad.selinux_audit_data = &sad; | ||
2782 | ad.u.dentry = dentry; | 2779 | ad.u.dentry = dentry; |
2783 | 2780 | ||
2784 | rc = avc_has_perm(sid, isec->sid, isec->sclass, | 2781 | rc = avc_has_perm(sid, isec->sid, isec->sclass, |
@@ -2788,8 +2785,25 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2788 | 2785 | ||
2789 | rc = security_context_to_sid(value, size, &newsid); | 2786 | rc = security_context_to_sid(value, size, &newsid); |
2790 | if (rc == -EINVAL) { | 2787 | if (rc == -EINVAL) { |
2791 | if (!capable(CAP_MAC_ADMIN)) | 2788 | if (!capable(CAP_MAC_ADMIN)) { |
2789 | struct audit_buffer *ab; | ||
2790 | size_t audit_size; | ||
2791 | const char *str; | ||
2792 | |||
2793 | /* We strip a nul only if it is at the end, otherwise the | ||
2794 | * context contains a nul and we should audit that */ | ||
2795 | str = value; | ||
2796 | if (str[size - 1] == '\0') | ||
2797 | audit_size = size - 1; | ||
2798 | else | ||
2799 | audit_size = size; | ||
2800 | ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR); | ||
2801 | audit_log_format(ab, "op=setxattr invalid_context="); | ||
2802 | audit_log_n_untrustedstring(ab, value, audit_size); | ||
2803 | audit_log_end(ab); | ||
2804 | |||
2792 | return rc; | 2805 | return rc; |
2806 | } | ||
2793 | rc = security_context_to_sid_force(value, size, &newsid); | 2807 | rc = security_context_to_sid_force(value, size, &newsid); |
2794 | } | 2808 | } |
2795 | if (rc) | 2809 | if (rc) |
@@ -2969,7 +2983,7 @@ static int selinux_file_permission(struct file *file, int mask) | |||
2969 | 2983 | ||
2970 | if (sid == fsec->sid && fsec->isid == isec->sid && | 2984 | if (sid == fsec->sid && fsec->isid == isec->sid && |
2971 | fsec->pseqno == avc_policy_seqno()) | 2985 | fsec->pseqno == avc_policy_seqno()) |
2972 | /* No change since dentry_open check. */ | 2986 | /* No change since file_open check. */ |
2973 | return 0; | 2987 | return 0; |
2974 | 2988 | ||
2975 | return selinux_revalidate_file_permission(file, mask); | 2989 | return selinux_revalidate_file_permission(file, mask); |
@@ -3228,15 +3242,13 @@ static int selinux_file_receive(struct file *file) | |||
3228 | return file_has_perm(cred, file, file_to_av(file)); | 3242 | return file_has_perm(cred, file, file_to_av(file)); |
3229 | } | 3243 | } |
3230 | 3244 | ||
3231 | static int selinux_dentry_open(struct file *file, const struct cred *cred) | 3245 | static int selinux_file_open(struct file *file, const struct cred *cred) |
3232 | { | 3246 | { |
3233 | struct file_security_struct *fsec; | 3247 | struct file_security_struct *fsec; |
3234 | struct inode *inode; | ||
3235 | struct inode_security_struct *isec; | 3248 | struct inode_security_struct *isec; |
3236 | 3249 | ||
3237 | inode = file->f_path.dentry->d_inode; | ||
3238 | fsec = file->f_security; | 3250 | fsec = file->f_security; |
3239 | isec = inode->i_security; | 3251 | isec = file->f_path.dentry->d_inode->i_security; |
3240 | /* | 3252 | /* |
3241 | * Save inode label and policy sequence number | 3253 | * Save inode label and policy sequence number |
3242 | * at open-time so that selinux_file_permission | 3254 | * at open-time so that selinux_file_permission |
@@ -3254,7 +3266,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred) | |||
3254 | * new inode label or new policy. | 3266 | * new inode label or new policy. |
3255 | * This check is not redundant - do not remove. | 3267 | * This check is not redundant - do not remove. |
3256 | */ | 3268 | */ |
3257 | return inode_has_perm_noadp(cred, inode, open_file_to_av(file), 0); | 3269 | return path_has_perm(cred, &file->f_path, open_file_to_av(file)); |
3258 | } | 3270 | } |
3259 | 3271 | ||
3260 | /* task security operations */ | 3272 | /* task security operations */ |
@@ -3373,12 +3385,10 @@ static int selinux_kernel_module_request(char *kmod_name) | |||
3373 | { | 3385 | { |
3374 | u32 sid; | 3386 | u32 sid; |
3375 | struct common_audit_data ad; | 3387 | struct common_audit_data ad; |
3376 | struct selinux_audit_data sad = {0,}; | ||
3377 | 3388 | ||
3378 | sid = task_sid(current); | 3389 | sid = task_sid(current); |
3379 | 3390 | ||
3380 | COMMON_AUDIT_DATA_INIT(&ad, KMOD); | 3391 | ad.type = LSM_AUDIT_DATA_KMOD; |
3381 | ad.selinux_audit_data = &sad; | ||
3382 | ad.u.kmod_name = kmod_name; | 3392 | ad.u.kmod_name = kmod_name; |
3383 | 3393 | ||
3384 | return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM, | 3394 | return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM, |
@@ -3751,15 +3761,13 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) | |||
3751 | { | 3761 | { |
3752 | struct sk_security_struct *sksec = sk->sk_security; | 3762 | struct sk_security_struct *sksec = sk->sk_security; |
3753 | struct common_audit_data ad; | 3763 | struct common_audit_data ad; |
3754 | struct selinux_audit_data sad = {0,}; | ||
3755 | struct lsm_network_audit net = {0,}; | 3764 | struct lsm_network_audit net = {0,}; |
3756 | u32 tsid = task_sid(task); | 3765 | u32 tsid = task_sid(task); |
3757 | 3766 | ||
3758 | if (sksec->sid == SECINITSID_KERNEL) | 3767 | if (sksec->sid == SECINITSID_KERNEL) |
3759 | return 0; | 3768 | return 0; |
3760 | 3769 | ||
3761 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3770 | ad.type = LSM_AUDIT_DATA_NET; |
3762 | ad.selinux_audit_data = &sad; | ||
3763 | ad.u.net = &net; | 3771 | ad.u.net = &net; |
3764 | ad.u.net->sk = sk; | 3772 | ad.u.net->sk = sk; |
3765 | 3773 | ||
@@ -3839,7 +3847,6 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3839 | char *addrp; | 3847 | char *addrp; |
3840 | struct sk_security_struct *sksec = sk->sk_security; | 3848 | struct sk_security_struct *sksec = sk->sk_security; |
3841 | struct common_audit_data ad; | 3849 | struct common_audit_data ad; |
3842 | struct selinux_audit_data sad = {0,}; | ||
3843 | struct lsm_network_audit net = {0,}; | 3850 | struct lsm_network_audit net = {0,}; |
3844 | struct sockaddr_in *addr4 = NULL; | 3851 | struct sockaddr_in *addr4 = NULL; |
3845 | struct sockaddr_in6 *addr6 = NULL; | 3852 | struct sockaddr_in6 *addr6 = NULL; |
@@ -3866,8 +3873,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3866 | snum, &sid); | 3873 | snum, &sid); |
3867 | if (err) | 3874 | if (err) |
3868 | goto out; | 3875 | goto out; |
3869 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3876 | ad.type = LSM_AUDIT_DATA_NET; |
3870 | ad.selinux_audit_data = &sad; | ||
3871 | ad.u.net = &net; | 3877 | ad.u.net = &net; |
3872 | ad.u.net->sport = htons(snum); | 3878 | ad.u.net->sport = htons(snum); |
3873 | ad.u.net->family = family; | 3879 | ad.u.net->family = family; |
@@ -3901,8 +3907,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3901 | if (err) | 3907 | if (err) |
3902 | goto out; | 3908 | goto out; |
3903 | 3909 | ||
3904 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3910 | ad.type = LSM_AUDIT_DATA_NET; |
3905 | ad.selinux_audit_data = &sad; | ||
3906 | ad.u.net = &net; | 3911 | ad.u.net = &net; |
3907 | ad.u.net->sport = htons(snum); | 3912 | ad.u.net->sport = htons(snum); |
3908 | ad.u.net->family = family; | 3913 | ad.u.net->family = family; |
@@ -3937,7 +3942,6 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3937 | if (sksec->sclass == SECCLASS_TCP_SOCKET || | 3942 | if (sksec->sclass == SECCLASS_TCP_SOCKET || |
3938 | sksec->sclass == SECCLASS_DCCP_SOCKET) { | 3943 | sksec->sclass == SECCLASS_DCCP_SOCKET) { |
3939 | struct common_audit_data ad; | 3944 | struct common_audit_data ad; |
3940 | struct selinux_audit_data sad = {0,}; | ||
3941 | struct lsm_network_audit net = {0,}; | 3945 | struct lsm_network_audit net = {0,}; |
3942 | struct sockaddr_in *addr4 = NULL; | 3946 | struct sockaddr_in *addr4 = NULL; |
3943 | struct sockaddr_in6 *addr6 = NULL; | 3947 | struct sockaddr_in6 *addr6 = NULL; |
@@ -3963,8 +3967,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3963 | perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ? | 3967 | perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ? |
3964 | TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; | 3968 | TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; |
3965 | 3969 | ||
3966 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3970 | ad.type = LSM_AUDIT_DATA_NET; |
3967 | ad.selinux_audit_data = &sad; | ||
3968 | ad.u.net = &net; | 3971 | ad.u.net = &net; |
3969 | ad.u.net->dport = htons(snum); | 3972 | ad.u.net->dport = htons(snum); |
3970 | ad.u.net->family = sk->sk_family; | 3973 | ad.u.net->family = sk->sk_family; |
@@ -4056,12 +4059,10 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, | |||
4056 | struct sk_security_struct *sksec_other = other->sk_security; | 4059 | struct sk_security_struct *sksec_other = other->sk_security; |
4057 | struct sk_security_struct *sksec_new = newsk->sk_security; | 4060 | struct sk_security_struct *sksec_new = newsk->sk_security; |
4058 | struct common_audit_data ad; | 4061 | struct common_audit_data ad; |
4059 | struct selinux_audit_data sad = {0,}; | ||
4060 | struct lsm_network_audit net = {0,}; | 4062 | struct lsm_network_audit net = {0,}; |
4061 | int err; | 4063 | int err; |
4062 | 4064 | ||
4063 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4065 | ad.type = LSM_AUDIT_DATA_NET; |
4064 | ad.selinux_audit_data = &sad; | ||
4065 | ad.u.net = &net; | 4066 | ad.u.net = &net; |
4066 | ad.u.net->sk = other; | 4067 | ad.u.net->sk = other; |
4067 | 4068 | ||
@@ -4090,11 +4091,9 @@ static int selinux_socket_unix_may_send(struct socket *sock, | |||
4090 | struct sk_security_struct *ssec = sock->sk->sk_security; | 4091 | struct sk_security_struct *ssec = sock->sk->sk_security; |
4091 | struct sk_security_struct *osec = other->sk->sk_security; | 4092 | struct sk_security_struct *osec = other->sk->sk_security; |
4092 | struct common_audit_data ad; | 4093 | struct common_audit_data ad; |
4093 | struct selinux_audit_data sad = {0,}; | ||
4094 | struct lsm_network_audit net = {0,}; | 4094 | struct lsm_network_audit net = {0,}; |
4095 | 4095 | ||
4096 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4096 | ad.type = LSM_AUDIT_DATA_NET; |
4097 | ad.selinux_audit_data = &sad; | ||
4098 | ad.u.net = &net; | 4097 | ad.u.net = &net; |
4099 | ad.u.net->sk = other->sk; | 4098 | ad.u.net->sk = other->sk; |
4100 | 4099 | ||
@@ -4132,12 +4131,10 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | |||
4132 | struct sk_security_struct *sksec = sk->sk_security; | 4131 | struct sk_security_struct *sksec = sk->sk_security; |
4133 | u32 sk_sid = sksec->sid; | 4132 | u32 sk_sid = sksec->sid; |
4134 | struct common_audit_data ad; | 4133 | struct common_audit_data ad; |
4135 | struct selinux_audit_data sad = {0,}; | ||
4136 | struct lsm_network_audit net = {0,}; | 4134 | struct lsm_network_audit net = {0,}; |
4137 | char *addrp; | 4135 | char *addrp; |
4138 | 4136 | ||
4139 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4137 | ad.type = LSM_AUDIT_DATA_NET; |
4140 | ad.selinux_audit_data = &sad; | ||
4141 | ad.u.net = &net; | 4138 | ad.u.net = &net; |
4142 | ad.u.net->netif = skb->skb_iif; | 4139 | ad.u.net->netif = skb->skb_iif; |
4143 | ad.u.net->family = family; | 4140 | ad.u.net->family = family; |
@@ -4167,7 +4164,6 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4167 | u16 family = sk->sk_family; | 4164 | u16 family = sk->sk_family; |
4168 | u32 sk_sid = sksec->sid; | 4165 | u32 sk_sid = sksec->sid; |
4169 | struct common_audit_data ad; | 4166 | struct common_audit_data ad; |
4170 | struct selinux_audit_data sad = {0,}; | ||
4171 | struct lsm_network_audit net = {0,}; | 4167 | struct lsm_network_audit net = {0,}; |
4172 | char *addrp; | 4168 | char *addrp; |
4173 | u8 secmark_active; | 4169 | u8 secmark_active; |
@@ -4192,8 +4188,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4192 | if (!secmark_active && !peerlbl_active) | 4188 | if (!secmark_active && !peerlbl_active) |
4193 | return 0; | 4189 | return 0; |
4194 | 4190 | ||
4195 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4191 | ad.type = LSM_AUDIT_DATA_NET; |
4196 | ad.selinux_audit_data = &sad; | ||
4197 | ad.u.net = &net; | 4192 | ad.u.net = &net; |
4198 | ad.u.net->netif = skb->skb_iif; | 4193 | ad.u.net->netif = skb->skb_iif; |
4199 | ad.u.net->family = family; | 4194 | ad.u.net->family = family; |
@@ -4531,7 +4526,6 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | |||
4531 | char *addrp; | 4526 | char *addrp; |
4532 | u32 peer_sid; | 4527 | u32 peer_sid; |
4533 | struct common_audit_data ad; | 4528 | struct common_audit_data ad; |
4534 | struct selinux_audit_data sad = {0,}; | ||
4535 | struct lsm_network_audit net = {0,}; | 4529 | struct lsm_network_audit net = {0,}; |
4536 | u8 secmark_active; | 4530 | u8 secmark_active; |
4537 | u8 netlbl_active; | 4531 | u8 netlbl_active; |
@@ -4549,8 +4543,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | |||
4549 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0) | 4543 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0) |
4550 | return NF_DROP; | 4544 | return NF_DROP; |
4551 | 4545 | ||
4552 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4546 | ad.type = LSM_AUDIT_DATA_NET; |
4553 | ad.selinux_audit_data = &sad; | ||
4554 | ad.u.net = &net; | 4547 | ad.u.net = &net; |
4555 | ad.u.net->netif = ifindex; | 4548 | ad.u.net->netif = ifindex; |
4556 | ad.u.net->family = family; | 4549 | ad.u.net->family = family; |
@@ -4640,7 +4633,6 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
4640 | struct sock *sk = skb->sk; | 4633 | struct sock *sk = skb->sk; |
4641 | struct sk_security_struct *sksec; | 4634 | struct sk_security_struct *sksec; |
4642 | struct common_audit_data ad; | 4635 | struct common_audit_data ad; |
4643 | struct selinux_audit_data sad = {0,}; | ||
4644 | struct lsm_network_audit net = {0,}; | 4636 | struct lsm_network_audit net = {0,}; |
4645 | char *addrp; | 4637 | char *addrp; |
4646 | u8 proto; | 4638 | u8 proto; |
@@ -4649,8 +4641,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
4649 | return NF_ACCEPT; | 4641 | return NF_ACCEPT; |
4650 | sksec = sk->sk_security; | 4642 | sksec = sk->sk_security; |
4651 | 4643 | ||
4652 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4644 | ad.type = LSM_AUDIT_DATA_NET; |
4653 | ad.selinux_audit_data = &sad; | ||
4654 | ad.u.net = &net; | 4645 | ad.u.net = &net; |
4655 | ad.u.net->netif = ifindex; | 4646 | ad.u.net->netif = ifindex; |
4656 | ad.u.net->family = family; | 4647 | ad.u.net->family = family; |
@@ -4675,7 +4666,6 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4675 | u32 peer_sid; | 4666 | u32 peer_sid; |
4676 | struct sock *sk; | 4667 | struct sock *sk; |
4677 | struct common_audit_data ad; | 4668 | struct common_audit_data ad; |
4678 | struct selinux_audit_data sad = {0,}; | ||
4679 | struct lsm_network_audit net = {0,}; | 4669 | struct lsm_network_audit net = {0,}; |
4680 | char *addrp; | 4670 | char *addrp; |
4681 | u8 secmark_active; | 4671 | u8 secmark_active; |
@@ -4722,8 +4712,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4722 | secmark_perm = PACKET__SEND; | 4712 | secmark_perm = PACKET__SEND; |
4723 | } | 4713 | } |
4724 | 4714 | ||
4725 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4715 | ad.type = LSM_AUDIT_DATA_NET; |
4726 | ad.selinux_audit_data = &sad; | ||
4727 | ad.u.net = &net; | 4716 | ad.u.net = &net; |
4728 | ad.u.net->netif = ifindex; | 4717 | ad.u.net->netif = ifindex; |
4729 | ad.u.net->family = family; | 4718 | ad.u.net->family = family; |
@@ -4841,13 +4830,11 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | |||
4841 | { | 4830 | { |
4842 | struct ipc_security_struct *isec; | 4831 | struct ipc_security_struct *isec; |
4843 | struct common_audit_data ad; | 4832 | struct common_audit_data ad; |
4844 | struct selinux_audit_data sad = {0,}; | ||
4845 | u32 sid = current_sid(); | 4833 | u32 sid = current_sid(); |
4846 | 4834 | ||
4847 | isec = ipc_perms->security; | 4835 | isec = ipc_perms->security; |
4848 | 4836 | ||
4849 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 4837 | ad.type = LSM_AUDIT_DATA_IPC; |
4850 | ad.selinux_audit_data = &sad; | ||
4851 | ad.u.ipc_id = ipc_perms->key; | 4838 | ad.u.ipc_id = ipc_perms->key; |
4852 | 4839 | ||
4853 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); | 4840 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); |
@@ -4868,7 +4855,6 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | |||
4868 | { | 4855 | { |
4869 | struct ipc_security_struct *isec; | 4856 | struct ipc_security_struct *isec; |
4870 | struct common_audit_data ad; | 4857 | struct common_audit_data ad; |
4871 | struct selinux_audit_data sad = {0,}; | ||
4872 | u32 sid = current_sid(); | 4858 | u32 sid = current_sid(); |
4873 | int rc; | 4859 | int rc; |
4874 | 4860 | ||
@@ -4878,8 +4864,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | |||
4878 | 4864 | ||
4879 | isec = msq->q_perm.security; | 4865 | isec = msq->q_perm.security; |
4880 | 4866 | ||
4881 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 4867 | ad.type = LSM_AUDIT_DATA_IPC; |
4882 | ad.selinux_audit_data = &sad; | ||
4883 | ad.u.ipc_id = msq->q_perm.key; | 4868 | ad.u.ipc_id = msq->q_perm.key; |
4884 | 4869 | ||
4885 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, | 4870 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
@@ -4900,13 +4885,11 @@ static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) | |||
4900 | { | 4885 | { |
4901 | struct ipc_security_struct *isec; | 4886 | struct ipc_security_struct *isec; |
4902 | struct common_audit_data ad; | 4887 | struct common_audit_data ad; |
4903 | struct selinux_audit_data sad = {0,}; | ||
4904 | u32 sid = current_sid(); | 4888 | u32 sid = current_sid(); |
4905 | 4889 | ||
4906 | isec = msq->q_perm.security; | 4890 | isec = msq->q_perm.security; |
4907 | 4891 | ||
4908 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 4892 | ad.type = LSM_AUDIT_DATA_IPC; |
4909 | ad.selinux_audit_data = &sad; | ||
4910 | ad.u.ipc_id = msq->q_perm.key; | 4893 | ad.u.ipc_id = msq->q_perm.key; |
4911 | 4894 | ||
4912 | return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, | 4895 | return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
@@ -4946,7 +4929,6 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
4946 | struct ipc_security_struct *isec; | 4929 | struct ipc_security_struct *isec; |
4947 | struct msg_security_struct *msec; | 4930 | struct msg_security_struct *msec; |
4948 | struct common_audit_data ad; | 4931 | struct common_audit_data ad; |
4949 | struct selinux_audit_data sad = {0,}; | ||
4950 | u32 sid = current_sid(); | 4932 | u32 sid = current_sid(); |
4951 | int rc; | 4933 | int rc; |
4952 | 4934 | ||
@@ -4967,8 +4949,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
4967 | return rc; | 4949 | return rc; |
4968 | } | 4950 | } |
4969 | 4951 | ||
4970 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 4952 | ad.type = LSM_AUDIT_DATA_IPC; |
4971 | ad.selinux_audit_data = &sad; | ||
4972 | ad.u.ipc_id = msq->q_perm.key; | 4953 | ad.u.ipc_id = msq->q_perm.key; |
4973 | 4954 | ||
4974 | /* Can this process write to the queue? */ | 4955 | /* Can this process write to the queue? */ |
@@ -4993,15 +4974,13 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
4993 | struct ipc_security_struct *isec; | 4974 | struct ipc_security_struct *isec; |
4994 | struct msg_security_struct *msec; | 4975 | struct msg_security_struct *msec; |
4995 | struct common_audit_data ad; | 4976 | struct common_audit_data ad; |
4996 | struct selinux_audit_data sad = {0,}; | ||
4997 | u32 sid = task_sid(target); | 4977 | u32 sid = task_sid(target); |
4998 | int rc; | 4978 | int rc; |
4999 | 4979 | ||
5000 | isec = msq->q_perm.security; | 4980 | isec = msq->q_perm.security; |
5001 | msec = msg->security; | 4981 | msec = msg->security; |
5002 | 4982 | ||
5003 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 4983 | ad.type = LSM_AUDIT_DATA_IPC; |
5004 | ad.selinux_audit_data = &sad; | ||
5005 | ad.u.ipc_id = msq->q_perm.key; | 4984 | ad.u.ipc_id = msq->q_perm.key; |
5006 | 4985 | ||
5007 | rc = avc_has_perm(sid, isec->sid, | 4986 | rc = avc_has_perm(sid, isec->sid, |
@@ -5017,7 +4996,6 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) | |||
5017 | { | 4996 | { |
5018 | struct ipc_security_struct *isec; | 4997 | struct ipc_security_struct *isec; |
5019 | struct common_audit_data ad; | 4998 | struct common_audit_data ad; |
5020 | struct selinux_audit_data sad = {0,}; | ||
5021 | u32 sid = current_sid(); | 4999 | u32 sid = current_sid(); |
5022 | int rc; | 5000 | int rc; |
5023 | 5001 | ||
@@ -5027,8 +5005,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) | |||
5027 | 5005 | ||
5028 | isec = shp->shm_perm.security; | 5006 | isec = shp->shm_perm.security; |
5029 | 5007 | ||
5030 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 5008 | ad.type = LSM_AUDIT_DATA_IPC; |
5031 | ad.selinux_audit_data = &sad; | ||
5032 | ad.u.ipc_id = shp->shm_perm.key; | 5009 | ad.u.ipc_id = shp->shm_perm.key; |
5033 | 5010 | ||
5034 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, | 5011 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
@@ -5049,13 +5026,11 @@ static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) | |||
5049 | { | 5026 | { |
5050 | struct ipc_security_struct *isec; | 5027 | struct ipc_security_struct *isec; |
5051 | struct common_audit_data ad; | 5028 | struct common_audit_data ad; |
5052 | struct selinux_audit_data sad = {0,}; | ||
5053 | u32 sid = current_sid(); | 5029 | u32 sid = current_sid(); |
5054 | 5030 | ||
5055 | isec = shp->shm_perm.security; | 5031 | isec = shp->shm_perm.security; |
5056 | 5032 | ||
5057 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 5033 | ad.type = LSM_AUDIT_DATA_IPC; |
5058 | ad.selinux_audit_data = &sad; | ||
5059 | ad.u.ipc_id = shp->shm_perm.key; | 5034 | ad.u.ipc_id = shp->shm_perm.key; |
5060 | 5035 | ||
5061 | return avc_has_perm(sid, isec->sid, SECCLASS_SHM, | 5036 | return avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
@@ -5113,7 +5088,6 @@ static int selinux_sem_alloc_security(struct sem_array *sma) | |||
5113 | { | 5088 | { |
5114 | struct ipc_security_struct *isec; | 5089 | struct ipc_security_struct *isec; |
5115 | struct common_audit_data ad; | 5090 | struct common_audit_data ad; |
5116 | struct selinux_audit_data sad = {0,}; | ||
5117 | u32 sid = current_sid(); | 5091 | u32 sid = current_sid(); |
5118 | int rc; | 5092 | int rc; |
5119 | 5093 | ||
@@ -5123,8 +5097,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma) | |||
5123 | 5097 | ||
5124 | isec = sma->sem_perm.security; | 5098 | isec = sma->sem_perm.security; |
5125 | 5099 | ||
5126 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 5100 | ad.type = LSM_AUDIT_DATA_IPC; |
5127 | ad.selinux_audit_data = &sad; | ||
5128 | ad.u.ipc_id = sma->sem_perm.key; | 5101 | ad.u.ipc_id = sma->sem_perm.key; |
5129 | 5102 | ||
5130 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, | 5103 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
@@ -5145,13 +5118,11 @@ static int selinux_sem_associate(struct sem_array *sma, int semflg) | |||
5145 | { | 5118 | { |
5146 | struct ipc_security_struct *isec; | 5119 | struct ipc_security_struct *isec; |
5147 | struct common_audit_data ad; | 5120 | struct common_audit_data ad; |
5148 | struct selinux_audit_data sad = {0,}; | ||
5149 | u32 sid = current_sid(); | 5121 | u32 sid = current_sid(); |
5150 | 5122 | ||
5151 | isec = sma->sem_perm.security; | 5123 | isec = sma->sem_perm.security; |
5152 | 5124 | ||
5153 | COMMON_AUDIT_DATA_INIT(&ad, IPC); | 5125 | ad.type = LSM_AUDIT_DATA_IPC; |
5154 | ad.selinux_audit_data = &sad; | ||
5155 | ad.u.ipc_id = sma->sem_perm.key; | 5126 | ad.u.ipc_id = sma->sem_perm.key; |
5156 | 5127 | ||
5157 | return avc_has_perm(sid, isec->sid, SECCLASS_SEM, | 5128 | return avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
@@ -5331,8 +5302,23 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5331 | } | 5302 | } |
5332 | error = security_context_to_sid(value, size, &sid); | 5303 | error = security_context_to_sid(value, size, &sid); |
5333 | if (error == -EINVAL && !strcmp(name, "fscreate")) { | 5304 | if (error == -EINVAL && !strcmp(name, "fscreate")) { |
5334 | if (!capable(CAP_MAC_ADMIN)) | 5305 | if (!capable(CAP_MAC_ADMIN)) { |
5306 | struct audit_buffer *ab; | ||
5307 | size_t audit_size; | ||
5308 | |||
5309 | /* We strip a nul only if it is at the end, otherwise the | ||
5310 | * context contains a nul and we should audit that */ | ||
5311 | if (str[size - 1] == '\0') | ||
5312 | audit_size = size - 1; | ||
5313 | else | ||
5314 | audit_size = size; | ||
5315 | ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR); | ||
5316 | audit_log_format(ab, "op=fscreate invalid_context="); | ||
5317 | audit_log_n_untrustedstring(ab, value, audit_size); | ||
5318 | audit_log_end(ab); | ||
5319 | |||
5335 | return error; | 5320 | return error; |
5321 | } | ||
5336 | error = security_context_to_sid_force(value, size, | 5322 | error = security_context_to_sid_force(value, size, |
5337 | &sid); | 5323 | &sid); |
5338 | } | 5324 | } |
@@ -5592,7 +5578,7 @@ static struct security_operations selinux_ops = { | |||
5592 | .file_send_sigiotask = selinux_file_send_sigiotask, | 5578 | .file_send_sigiotask = selinux_file_send_sigiotask, |
5593 | .file_receive = selinux_file_receive, | 5579 | .file_receive = selinux_file_receive, |
5594 | 5580 | ||
5595 | .dentry_open = selinux_dentry_open, | 5581 | .file_open = selinux_file_open, |
5596 | 5582 | ||
5597 | .task_create = selinux_task_create, | 5583 | .task_create = selinux_task_create, |
5598 | .cred_alloc_blank = selinux_cred_alloc_blank, | 5584 | .cred_alloc_blank = selinux_cred_alloc_blank, |