aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/security.h41
-rw-r--r--security/dummy.c7
-rw-r--r--security/selinux/hooks.c59
-rw-r--r--security/selinux/include/objsec.h1
4 files changed, 108 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,
diff --git a/security/dummy.c b/security/dummy.c
index 6ff887586479..e8a00fa80469 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -258,6 +258,12 @@ static void dummy_inode_free_security (struct inode *inode)
258 return; 258 return;
259} 259}
260 260
261static int dummy_inode_init_security (struct inode *inode, struct inode *dir,
262 char **name, void **value, size_t *len)
263{
264 return -EOPNOTSUPP;
265}
266
261static int dummy_inode_create (struct inode *inode, struct dentry *dentry, 267static int dummy_inode_create (struct inode *inode, struct dentry *dentry,
262 int mask) 268 int mask)
263{ 269{
@@ -886,6 +892,7 @@ void security_fixup_ops (struct security_operations *ops)
886 set_to_dummy_if_null(ops, sb_post_pivotroot); 892 set_to_dummy_if_null(ops, sb_post_pivotroot);
887 set_to_dummy_if_null(ops, inode_alloc_security); 893 set_to_dummy_if_null(ops, inode_alloc_security);
888 set_to_dummy_if_null(ops, inode_free_security); 894 set_to_dummy_if_null(ops, inode_free_security);
895 set_to_dummy_if_null(ops, inode_init_security);
889 set_to_dummy_if_null(ops, inode_create); 896 set_to_dummy_if_null(ops, inode_create);
890 set_to_dummy_if_null(ops, inode_post_create); 897 set_to_dummy_if_null(ops, inode_post_create);
891 set_to_dummy_if_null(ops, inode_link); 898 set_to_dummy_if_null(ops, inode_link);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8641f8894b4c..63701fe0e1ad 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1274,6 +1274,7 @@ static int post_create(struct inode *dir,
1274 struct inode *inode; 1274 struct inode *inode;
1275 struct inode_security_struct *dsec; 1275 struct inode_security_struct *dsec;
1276 struct superblock_security_struct *sbsec; 1276 struct superblock_security_struct *sbsec;
1277 struct inode_security_struct *isec;
1277 u32 newsid; 1278 u32 newsid;
1278 char *context; 1279 char *context;
1279 unsigned int len; 1280 unsigned int len;
@@ -1293,6 +1294,11 @@ static int post_create(struct inode *dir,
1293 return 0; 1294 return 0;
1294 } 1295 }
1295 1296
1297 isec = inode->i_security;
1298
1299 if (isec->security_attr_init)
1300 return 0;
1301
1296 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) { 1302 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
1297 newsid = tsec->create_sid; 1303 newsid = tsec->create_sid;
1298 } else { 1304 } else {
@@ -2018,6 +2024,58 @@ static void selinux_inode_free_security(struct inode *inode)
2018 inode_free_security(inode); 2024 inode_free_security(inode);
2019} 2025}
2020 2026
2027static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2028 char **name, void **value,
2029 size_t *len)
2030{
2031 struct task_security_struct *tsec;
2032 struct inode_security_struct *dsec;
2033 struct superblock_security_struct *sbsec;
2034 struct inode_security_struct *isec;
2035 u32 newsid;
2036 int rc;
2037 char *namep, *context;
2038
2039 tsec = current->security;
2040 dsec = dir->i_security;
2041 sbsec = dir->i_sb->s_security;
2042 isec = inode->i_security;
2043
2044 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
2045 newsid = tsec->create_sid;
2046 } else {
2047 rc = security_transition_sid(tsec->sid, dsec->sid,
2048 inode_mode_to_security_class(inode->i_mode),
2049 &newsid);
2050 if (rc) {
2051 printk(KERN_WARNING "%s: "
2052 "security_transition_sid failed, rc=%d (dev=%s "
2053 "ino=%ld)\n",
2054 __FUNCTION__,
2055 -rc, inode->i_sb->s_id, inode->i_ino);
2056 return rc;
2057 }
2058 }
2059
2060 inode_security_set_sid(inode, newsid);
2061
2062 namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
2063 if (!namep)
2064 return -ENOMEM;
2065 *name = namep;
2066
2067 rc = security_sid_to_context(newsid, &context, len);
2068 if (rc) {
2069 kfree(namep);
2070 return rc;
2071 }
2072 *value = context;
2073
2074 isec->security_attr_init = 1;
2075
2076 return 0;
2077}
2078
2021static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask) 2079static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
2022{ 2080{
2023 return may_create(dir, dentry, SECCLASS_FILE); 2081 return may_create(dir, dentry, SECCLASS_FILE);
@@ -4298,6 +4356,7 @@ static struct security_operations selinux_ops = {
4298 4356
4299 .inode_alloc_security = selinux_inode_alloc_security, 4357 .inode_alloc_security = selinux_inode_alloc_security,
4300 .inode_free_security = selinux_inode_free_security, 4358 .inode_free_security = selinux_inode_free_security,
4359 .inode_init_security = selinux_inode_init_security,
4301 .inode_create = selinux_inode_create, 4360 .inode_create = selinux_inode_create,
4302 .inode_post_create = selinux_inode_post_create, 4361 .inode_post_create = selinux_inode_post_create,
4303 .inode_link = selinux_inode_link, 4362 .inode_link = selinux_inode_link,
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 887937c8134a..c515bc0b58a1 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -46,6 +46,7 @@ struct inode_security_struct {
46 unsigned char initialized; /* initialization flag */ 46 unsigned char initialized; /* initialization flag */
47 struct semaphore sem; 47 struct semaphore sem;
48 unsigned char inherit; /* inherit SID from parent entry */ 48 unsigned char inherit; /* inherit SID from parent entry */
49 unsigned char security_attr_init; /* security attributes init flag */
49}; 50};
50 51
51struct file_security_struct { 52struct file_security_struct {