aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2005-09-09 16:01:43 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:57:28 -0400
commit570bc1c2e5ccdb408081e77507a385dc7ebed7fa (patch)
treed00d2df7c93899fa2028128c40961fec46ede471
parentac50960afa31877493add6d941d8402fa879c452 (diff)
[PATCH] tmpfs: Enable atomic inode security labeling
This patch modifies tmpfs to call the inode_init_security LSM hook to set up the incore inode security state for new inodes before the inode becomes accessible via the dcache. As there is no underlying storage of security xattrs in this case, it is not necessary for the hook to return the (name, value, len) triple to the tmpfs code, so this patch also modifies the SELinux hook function to correctly handle the case where the (name, value, len) pointers are NULL. The hook call is needed in tmpfs in order to support proper security labeling of tmpfs inodes (e.g. for udev with tmpfs /dev in Fedora). With this change in place, we should then be able to remove the security_inode_post_create/mkdir/... hooks safely. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Cc: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--mm/shmem.c20
-rw-r--r--security/selinux/hooks.c27
2 files changed, 35 insertions, 12 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index 0d627a37da95..1f7aeb210c7b 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1608,6 +1608,15 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1608 int error = -ENOSPC; 1608 int error = -ENOSPC;
1609 1609
1610 if (inode) { 1610 if (inode) {
1611 error = security_inode_init_security(inode, dir, NULL, NULL,
1612 NULL);
1613 if (error) {
1614 if (error != -EOPNOTSUPP) {
1615 iput(inode);
1616 return error;
1617 }
1618 error = 0;
1619 }
1611 if (dir->i_mode & S_ISGID) { 1620 if (dir->i_mode & S_ISGID) {
1612 inode->i_gid = dir->i_gid; 1621 inode->i_gid = dir->i_gid;
1613 if (S_ISDIR(mode)) 1622 if (S_ISDIR(mode))
@@ -1617,7 +1626,6 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1617 dir->i_ctime = dir->i_mtime = CURRENT_TIME; 1626 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
1618 d_instantiate(dentry, inode); 1627 d_instantiate(dentry, inode);
1619 dget(dentry); /* Extra count - pin the dentry in core */ 1628 dget(dentry); /* Extra count - pin the dentry in core */
1620 error = 0;
1621 } 1629 }
1622 return error; 1630 return error;
1623} 1631}
@@ -1747,6 +1755,16 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
1747 if (!inode) 1755 if (!inode)
1748 return -ENOSPC; 1756 return -ENOSPC;
1749 1757
1758 error = security_inode_init_security(inode, dir, NULL, NULL,
1759 NULL);
1760 if (error) {
1761 if (error != -EOPNOTSUPP) {
1762 iput(inode);
1763 return error;
1764 }
1765 error = 0;
1766 }
1767
1750 info = SHMEM_I(inode); 1768 info = SHMEM_I(inode);
1751 inode->i_size = len-1; 1769 inode->i_size = len-1;
1752 if (len <= (char *)inode - (char *)info) { 1770 if (len <= (char *)inode - (char *)info) {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 63701fe0e1ad..265f33d3af9b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2032,9 +2032,9 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2032 struct inode_security_struct *dsec; 2032 struct inode_security_struct *dsec;
2033 struct superblock_security_struct *sbsec; 2033 struct superblock_security_struct *sbsec;
2034 struct inode_security_struct *isec; 2034 struct inode_security_struct *isec;
2035 u32 newsid; 2035 u32 newsid, clen;
2036 int rc; 2036 int rc;
2037 char *namep, *context; 2037 char *namep = NULL, *context;
2038 2038
2039 tsec = current->security; 2039 tsec = current->security;
2040 dsec = dir->i_security; 2040 dsec = dir->i_security;
@@ -2059,17 +2059,22 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2059 2059
2060 inode_security_set_sid(inode, newsid); 2060 inode_security_set_sid(inode, newsid);
2061 2061
2062 namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL); 2062 if (name) {
2063 if (!namep) 2063 namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
2064 return -ENOMEM; 2064 if (!namep)
2065 *name = namep; 2065 return -ENOMEM;
2066 *name = namep;
2067 }
2066 2068
2067 rc = security_sid_to_context(newsid, &context, len); 2069 if (value && len) {
2068 if (rc) { 2070 rc = security_sid_to_context(newsid, &context, &clen);
2069 kfree(namep); 2071 if (rc) {
2070 return rc; 2072 kfree(namep);
2073 return rc;
2074 }
2075 *value = context;
2076 *len = clen;
2071 } 2077 }
2072 *value = context;
2073 2078
2074 isec->security_attr_init = 1; 2079 isec->security_attr_init = 1;
2075 2080