diff options
author | David Howells <dhowells@redhat.com> | 2015-07-10 17:19:58 -0400 |
---|---|---|
committer | Paul Moore <pmoore@redhat.com> | 2015-07-13 13:31:59 -0400 |
commit | c3c188b2c3ed29effe8693672ee1c84184103b4e (patch) | |
tree | 54782e4ec8029c70b7acf0ad684a34b7b1e84b98 /security/selinux/hooks.c | |
parent | bd1741f4cf05d7709348f591d16eeb5f786de673 (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/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 87 |
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 | */ | ||
1715 | static 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. */ |
1713 | static int may_create(struct inode *dir, | 1739 | static 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) { |