aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2015-07-10 17:19:58 -0400
committerPaul Moore <pmoore@redhat.com>2015-07-13 13:31:59 -0400
commitc3c188b2c3ed29effe8693672ee1c84184103b4e (patch)
tree54782e4ec8029c70b7acf0ad684a34b7b1e84b98 /security
parentbd1741f4cf05d7709348f591d16eeb5f786de673 (diff)
selinux: Create a common helper to determine an inode label [ver #3]
Create a common helper function to determine the label for a new inode. This is then used by: - may_create() - selinux_dentry_init_security() - selinux_inode_init_security() This will change the behaviour of the functions slightly, bringing them all into line. Suggested-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: Paul Moore <pmoore@redhat.com>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c87
1 files changed, 41 insertions, 46 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ef310f82717d..f4be0a110788 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1709,6 +1709,32 @@ out:
1709 return rc; 1709 return rc;
1710} 1710}
1711 1711
1712/*
1713 * Determine the label for an inode that might be unioned.
1714 */
1715static int selinux_determine_inode_label(const struct inode *dir,
1716 const struct qstr *name,
1717 u16 tclass,
1718 u32 *_new_isid)
1719{
1720 const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
1721 const struct inode_security_struct *dsec = dir->i_security;
1722 const struct task_security_struct *tsec = current_security();
1723
1724 if ((sbsec->flags & SE_SBINITIALIZED) &&
1725 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
1726 *_new_isid = sbsec->mntpoint_sid;
1727 } else if ((sbsec->flags & SBLABEL_MNT) &&
1728 tsec->create_sid) {
1729 *_new_isid = tsec->create_sid;
1730 } else {
1731 return security_transition_sid(tsec->sid, dsec->sid, tclass,
1732 name, _new_isid);
1733 }
1734
1735 return 0;
1736}
1737
1712/* Check whether a task can create a file. */ 1738/* Check whether a task can create a file. */
1713static int may_create(struct inode *dir, 1739static int may_create(struct inode *dir,
1714 struct dentry *dentry, 1740 struct dentry *dentry,
@@ -1725,7 +1751,6 @@ static int may_create(struct inode *dir,
1725 sbsec = dir->i_sb->s_security; 1751 sbsec = dir->i_sb->s_security;
1726 1752
1727 sid = tsec->sid; 1753 sid = tsec->sid;
1728 newsid = tsec->create_sid;
1729 1754
1730 ad.type = LSM_AUDIT_DATA_DENTRY; 1755 ad.type = LSM_AUDIT_DATA_DENTRY;
1731 ad.u.dentry = dentry; 1756 ad.u.dentry = dentry;
@@ -1736,12 +1761,10 @@ static int may_create(struct inode *dir,
1736 if (rc) 1761 if (rc)
1737 return rc; 1762 return rc;
1738 1763
1739 if (!newsid || !(sbsec->flags & SBLABEL_MNT)) { 1764 rc = selinux_determine_inode_label(dir, &dentry->d_name, tclass,
1740 rc = security_transition_sid(sid, dsec->sid, tclass, 1765 &newsid);
1741 &dentry->d_name, &newsid); 1766 if (rc)
1742 if (rc) 1767 return rc;
1743 return rc;
1744 }
1745 1768
1746 rc = avc_has_perm(sid, newsid, tclass, FILE__CREATE, &ad); 1769 rc = avc_has_perm(sid, newsid, tclass, FILE__CREATE, &ad);
1747 if (rc) 1770 if (rc)
@@ -2715,32 +2738,14 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
2715 struct qstr *name, void **ctx, 2738 struct qstr *name, void **ctx,
2716 u32 *ctxlen) 2739 u32 *ctxlen)
2717{ 2740{
2718 const struct cred *cred = current_cred();
2719 struct task_security_struct *tsec;
2720 struct inode_security_struct *dsec;
2721 struct superblock_security_struct *sbsec;
2722 struct inode *dir = d_backing_inode(dentry->d_parent);
2723 u32 newsid; 2741 u32 newsid;
2724 int rc; 2742 int rc;
2725 2743
2726 tsec = cred->security; 2744 rc = selinux_determine_inode_label(d_inode(dentry->d_parent), name,
2727 dsec = dir->i_security; 2745 inode_mode_to_security_class(mode),
2728 sbsec = dir->i_sb->s_security; 2746 &newsid);
2729 2747 if (rc)
2730 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) { 2748 return rc;
2731 newsid = tsec->create_sid;
2732 } else {
2733 rc = security_transition_sid(tsec->sid, dsec->sid,
2734 inode_mode_to_security_class(mode),
2735 name,
2736 &newsid);
2737 if (rc) {
2738 printk(KERN_WARNING
2739 "%s: security_transition_sid failed, rc=%d\n",
2740 __func__, -rc);
2741 return rc;
2742 }
2743 }
2744 2749
2745 return security_sid_to_context(newsid, (char **)ctx, ctxlen); 2750 return security_sid_to_context(newsid, (char **)ctx, ctxlen);
2746} 2751}
@@ -2763,22 +2768,12 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2763 sid = tsec->sid; 2768 sid = tsec->sid;
2764 newsid = tsec->create_sid; 2769 newsid = tsec->create_sid;
2765 2770
2766 if ((sbsec->flags & SE_SBINITIALIZED) && 2771 rc = selinux_determine_inode_label(
2767 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) 2772 dir, qstr,
2768 newsid = sbsec->mntpoint_sid; 2773 inode_mode_to_security_class(inode->i_mode),
2769 else if (!newsid || !(sbsec->flags & SBLABEL_MNT)) { 2774 &newsid);
2770 rc = security_transition_sid(sid, dsec->sid, 2775 if (rc)
2771 inode_mode_to_security_class(inode->i_mode), 2776 return rc;
2772 qstr, &newsid);
2773 if (rc) {
2774 printk(KERN_WARNING "%s: "
2775 "security_transition_sid failed, rc=%d (dev=%s "
2776 "ino=%ld)\n",
2777 __func__,
2778 -rc, inode->i_sb->s_id, inode->i_ino);
2779 return rc;
2780 }
2781 }
2782 2777
2783 /* Possibly defer initialization to selinux_complete_init. */ 2778 /* Possibly defer initialization to selinux_complete_init. */
2784 if (sbsec->flags & SE_SBINITIALIZED) { 2779 if (sbsec->flags & SE_SBINITIALIZED) {