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.c96
1 files changed, 45 insertions, 51 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b65c201e9ff5..9c08a19cc81b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -117,6 +117,32 @@ static struct security_operations *secondary_ops = NULL;
117static LIST_HEAD(superblock_security_head); 117static LIST_HEAD(superblock_security_head);
118static DEFINE_SPINLOCK(sb_security_lock); 118static DEFINE_SPINLOCK(sb_security_lock);
119 119
120/* Return security context for a given sid or just the context
121 length if the buffer is null or length is 0 */
122static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
123{
124 char *context;
125 unsigned len;
126 int rc;
127
128 rc = security_sid_to_context(sid, &context, &len);
129 if (rc)
130 return rc;
131
132 if (!buffer || !size)
133 goto getsecurity_exit;
134
135 if (size < len) {
136 len = -ERANGE;
137 goto getsecurity_exit;
138 }
139 memcpy(buffer, context, len);
140
141getsecurity_exit:
142 kfree(context);
143 return len;
144}
145
120/* Allocate and free functions for each kind of security blob. */ 146/* Allocate and free functions for each kind of security blob. */
121 147
122static int task_alloc_security(struct task_struct *task) 148static int task_alloc_security(struct task_struct *task)
@@ -2209,6 +2235,11 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2209 return -EACCES; 2235 return -EACCES;
2210} 2236}
2211 2237
2238static const char *selinux_inode_xattr_getsuffix(void)
2239{
2240 return XATTR_SELINUX_SUFFIX;
2241}
2242
2212/* 2243/*
2213 * Copy the in-core inode security context value to the user. If the 2244 * Copy the in-core inode security context value to the user. If the
2214 * getxattr() prior to this succeeded, check to see if we need to 2245 * getxattr() prior to this succeeded, check to see if we need to
@@ -2219,44 +2250,11 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2219static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) 2250static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
2220{ 2251{
2221 struct inode_security_struct *isec = inode->i_security; 2252 struct inode_security_struct *isec = inode->i_security;
2222 char *context;
2223 unsigned len;
2224 int rc;
2225
2226 if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
2227 rc = -EOPNOTSUPP;
2228 goto out;
2229 }
2230
2231 rc = security_sid_to_context(isec->sid, &context, &len);
2232 if (rc)
2233 goto out;
2234
2235 /* Probe for required buffer size */
2236 if (!buffer || !size) {
2237 rc = len;
2238 goto out_free;
2239 }
2240 2253
2241 if (size < len) { 2254 if (strcmp(name, XATTR_SELINUX_SUFFIX))
2242 rc = -ERANGE; 2255 return -EOPNOTSUPP;
2243 goto out_free;
2244 }
2245 2256
2246 if (err > 0) { 2257 return selinux_getsecurity(isec->sid, buffer, size);
2247 if ((len == err) && !(memcmp(context, buffer, len))) {
2248 /* Don't need to canonicalize value */
2249 rc = err;
2250 goto out_free;
2251 }
2252 memset(buffer, 0, size);
2253 }
2254 memcpy(buffer, context, len);
2255 rc = len;
2256out_free:
2257 kfree(context);
2258out:
2259 return rc;
2260} 2258}
2261 2259
2262static int selinux_inode_setsecurity(struct inode *inode, const char *name, 2260static int selinux_inode_setsecurity(struct inode *inode, const char *name,
@@ -4022,6 +4020,13 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
4022 return ipc_has_perm(ipcp, av); 4020 return ipc_has_perm(ipcp, av);
4023} 4021}
4024 4022
4023static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
4024{
4025 struct ipc_security_struct *isec = ipcp->security;
4026
4027 return selinux_getsecurity(isec->sid, buffer, size);
4028}
4029
4025/* module stacking operations */ 4030/* module stacking operations */
4026static int selinux_register_security (const char *name, struct security_operations *ops) 4031static int selinux_register_security (const char *name, struct security_operations *ops)
4027{ 4032{
@@ -4063,8 +4068,7 @@ static int selinux_getprocattr(struct task_struct *p,
4063 char *name, void *value, size_t size) 4068 char *name, void *value, size_t size)
4064{ 4069{
4065 struct task_security_struct *tsec; 4070 struct task_security_struct *tsec;
4066 u32 sid, len; 4071 u32 sid;
4067 char *context;
4068 int error; 4072 int error;
4069 4073
4070 if (current != p) { 4074 if (current != p) {
@@ -4073,9 +4077,6 @@ static int selinux_getprocattr(struct task_struct *p,
4073 return error; 4077 return error;
4074 } 4078 }
4075 4079
4076 if (!size)
4077 return -ERANGE;
4078
4079 tsec = p->security; 4080 tsec = p->security;
4080 4081
4081 if (!strcmp(name, "current")) 4082 if (!strcmp(name, "current"))
@@ -4092,16 +4093,7 @@ static int selinux_getprocattr(struct task_struct *p,
4092 if (!sid) 4093 if (!sid)
4093 return 0; 4094 return 0;
4094 4095
4095 error = security_sid_to_context(sid, &context, &len); 4096 return selinux_getsecurity(sid, value, size);
4096 if (error)
4097 return error;
4098 if (len > size) {
4099 kfree(context);
4100 return -ERANGE;
4101 }
4102 memcpy(value, context, len);
4103 kfree(context);
4104 return len;
4105} 4097}
4106 4098
4107static int selinux_setprocattr(struct task_struct *p, 4099static int selinux_setprocattr(struct task_struct *p,
@@ -4259,6 +4251,7 @@ static struct security_operations selinux_ops = {
4259 .inode_getxattr = selinux_inode_getxattr, 4251 .inode_getxattr = selinux_inode_getxattr,
4260 .inode_listxattr = selinux_inode_listxattr, 4252 .inode_listxattr = selinux_inode_listxattr,
4261 .inode_removexattr = selinux_inode_removexattr, 4253 .inode_removexattr = selinux_inode_removexattr,
4254 .inode_xattr_getsuffix = selinux_inode_xattr_getsuffix,
4262 .inode_getsecurity = selinux_inode_getsecurity, 4255 .inode_getsecurity = selinux_inode_getsecurity,
4263 .inode_setsecurity = selinux_inode_setsecurity, 4256 .inode_setsecurity = selinux_inode_setsecurity,
4264 .inode_listsecurity = selinux_inode_listsecurity, 4257 .inode_listsecurity = selinux_inode_listsecurity,
@@ -4296,6 +4289,7 @@ static struct security_operations selinux_ops = {
4296 .task_to_inode = selinux_task_to_inode, 4289 .task_to_inode = selinux_task_to_inode,
4297 4290
4298 .ipc_permission = selinux_ipc_permission, 4291 .ipc_permission = selinux_ipc_permission,
4292 .ipc_getsecurity = selinux_ipc_getsecurity,
4299 4293
4300 .msg_msg_alloc_security = selinux_msg_msg_alloc_security, 4294 .msg_msg_alloc_security = selinux_msg_msg_alloc_security,
4301 .msg_msg_free_security = selinux_msg_msg_free_security, 4295 .msg_msg_free_security = selinux_msg_msg_free_security,