diff options
author | Stephen Smalley <sds@tycho.nsa.gov> | 2005-09-09 16:01:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-09 16:57:28 -0400 |
commit | 570bc1c2e5ccdb408081e77507a385dc7ebed7fa (patch) | |
tree | d00d2df7c93899fa2028128c40961fec46ede471 | |
parent | ac50960afa31877493add6d941d8402fa879c452 (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.c | 20 | ||||
-rw-r--r-- | security/selinux/hooks.c | 27 |
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 | ||