aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c59
1 files changed, 59 insertions, 0 deletions
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,