diff options
Diffstat (limited to 'security')
| -rw-r--r-- | security/dummy.c | 7 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 59 | ||||
| -rw-r--r-- | security/selinux/include/objsec.h | 1 |
3 files changed, 67 insertions, 0 deletions
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 | ||
| 261 | static 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 | |||
| 261 | static int dummy_inode_create (struct inode *inode, struct dentry *dentry, | 267 | static 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 | ||
| 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 { |
