aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2005-09-09 16:01:35 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:57:27 -0400
commit5e41ff9e0650f327a6c819841fa412da95d57319 (patch)
treea525df8bda34c2aa52f30326f94cd15109bb58b3 /include/linux
parentf5ee56cc184e0944ebc9ff1691985219959596f6 (diff)
[PATCH] security: enable atomic inode security labeling
The following patch set enables atomic security labeling of newly created inodes by altering the fs code to invoke a new LSM hook to obtain the security attribute to apply to a newly created inode and to set up the incore inode security state during the inode creation transaction. This parallels the existing processing for setting ACLs on newly created inodes. Otherwise, it is possible for new inodes to be accessed by another thread via the dcache prior to complete security setup (presently handled by the post_create/mkdir/... LSM hooks in the VFS) and a newly created inode may be left unlabeled on the disk in the event of a crash. SELinux presently works around the issue by ensuring that the incore inode security label is initialized to a special SID that is inaccessible to unprivileged processes (in accordance with policy), thereby preventing inappropriate access but potentially causing false denials on legitimate accesses. A simple test program demonstrates such false denials on SELinux, and the patch solves the problem. Similar such false denials have been encountered in real applications. This patch defines a new inode_init_security LSM hook to obtain the security attribute to apply to a newly created inode and to set up the incore inode security state for it, and adds a corresponding hook function implementation to SELinux. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/security.h41
1 files changed, 41 insertions, 0 deletions
diff --git a/include/linux/security.h b/include/linux/security.h
index 7aab6ab7c57f..d4f3b7a94ea6 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -250,6 +250,25 @@ struct swap_info_struct;
250 * @inode contains the inode structure. 250 * @inode contains the inode structure.
251 * Deallocate the inode security structure and set @inode->i_security to 251 * Deallocate the inode security structure and set @inode->i_security to
252 * NULL. 252 * NULL.
253 * @inode_init_security:
254 * Obtain the security attribute name suffix and value to set on a newly
255 * created inode and set up the incore security field for the new inode.
256 * This hook is called by the fs code as part of the inode creation
257 * transaction and provides for atomic labeling of the inode, unlike
258 * the post_create/mkdir/... hooks called by the VFS. The hook function
259 * is expected to allocate the name and value via kmalloc, with the caller
260 * being responsible for calling kfree after using them.
261 * If the security module does not use security attributes or does
262 * not wish to put a security attribute on this particular inode,
263 * then it should return -EOPNOTSUPP to skip this processing.
264 * @inode contains the inode structure of the newly created inode.
265 * @dir contains the inode structure of the parent directory.
266 * @name will be set to the allocated name suffix (e.g. selinux).
267 * @value will be set to the allocated attribute value.
268 * @len will be set to the length of the value.
269 * Returns 0 if @name and @value have been successfully set,
270 * -EOPNOTSUPP if no security attribute is needed, or
271 * -ENOMEM on memory allocation failure.
253 * @inode_create: 272 * @inode_create:
254 * Check permission to create a regular file. 273 * Check permission to create a regular file.
255 * @dir contains inode structure of the parent of the new file. 274 * @dir contains inode structure of the parent of the new file.
@@ -1080,6 +1099,8 @@ struct security_operations {
1080 1099
1081 int (*inode_alloc_security) (struct inode *inode); 1100 int (*inode_alloc_security) (struct inode *inode);
1082 void (*inode_free_security) (struct inode *inode); 1101 void (*inode_free_security) (struct inode *inode);
1102 int (*inode_init_security) (struct inode *inode, struct inode *dir,
1103 char **name, void **value, size_t *len);
1083 int (*inode_create) (struct inode *dir, 1104 int (*inode_create) (struct inode *dir,
1084 struct dentry *dentry, int mode); 1105 struct dentry *dentry, int mode);
1085 void (*inode_post_create) (struct inode *dir, 1106 void (*inode_post_create) (struct inode *dir,
@@ -1442,6 +1463,17 @@ static inline void security_inode_free (struct inode *inode)
1442 return; 1463 return;
1443 security_ops->inode_free_security (inode); 1464 security_ops->inode_free_security (inode);
1444} 1465}
1466
1467static inline int security_inode_init_security (struct inode *inode,
1468 struct inode *dir,
1469 char **name,
1470 void **value,
1471 size_t *len)
1472{
1473 if (unlikely (IS_PRIVATE (inode)))
1474 return -EOPNOTSUPP;
1475 return security_ops->inode_init_security (inode, dir, name, value, len);
1476}
1445 1477
1446static inline int security_inode_create (struct inode *dir, 1478static inline int security_inode_create (struct inode *dir,
1447 struct dentry *dentry, 1479 struct dentry *dentry,
@@ -2171,6 +2203,15 @@ static inline int security_inode_alloc (struct inode *inode)
2171 2203
2172static inline void security_inode_free (struct inode *inode) 2204static inline void security_inode_free (struct inode *inode)
2173{ } 2205{ }
2206
2207static inline int security_inode_init_security (struct inode *inode,
2208 struct inode *dir,
2209 char **name,
2210 void **value,
2211 size_t *len)
2212{
2213 return -EOPNOTSUPP;
2214}
2174 2215
2175static inline int security_inode_create (struct inode *dir, 2216static inline int security_inode_create (struct inode *dir,
2176 struct dentry *dentry, 2217 struct dentry *dentry,