diff options
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/hooks.c | 59 | ||||
-rw-r--r-- | security/selinux/include/objsec.h | 1 |
2 files changed, 60 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 | ||
2027 | static 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 | |||
2021 | static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask) | 2079 | static 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 | ||
51 | struct file_security_struct { | 52 | struct file_security_struct { |