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.c98
1 files changed, 46 insertions, 52 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ccaf988f3729..b61b9554bc27 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -119,6 +119,32 @@ static DEFINE_SPINLOCK(sb_security_lock);
119 119
120static kmem_cache_t *sel_inode_cache; 120static kmem_cache_t *sel_inode_cache;
121 121
122/* Return security context for a given sid or just the context
123 length if the buffer is null or length is 0 */
124static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
125{
126 char *context;
127 unsigned len;
128 int rc;
129
130 rc = security_sid_to_context(sid, &context, &len);
131 if (rc)
132 return rc;
133
134 if (!buffer || !size)
135 goto getsecurity_exit;
136
137 if (size < len) {
138 len = -ERANGE;
139 goto getsecurity_exit;
140 }
141 memcpy(buffer, context, len);
142
143getsecurity_exit:
144 kfree(context);
145 return len;
146}
147
122/* Allocate and free functions for each kind of security blob. */ 148/* Allocate and free functions for each kind of security blob. */
123 149
124static int task_alloc_security(struct task_struct *task) 150static int task_alloc_security(struct task_struct *task)
@@ -2210,6 +2236,11 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2210 return -EACCES; 2236 return -EACCES;
2211} 2237}
2212 2238
2239static const char *selinux_inode_xattr_getsuffix(void)
2240{
2241 return XATTR_SELINUX_SUFFIX;
2242}
2243
2213/* 2244/*
2214 * Copy the in-core inode security context value to the user. If the 2245 * Copy the in-core inode security context value to the user. If the
2215 * getxattr() prior to this succeeded, check to see if we need to 2246 * getxattr() prior to this succeeded, check to see if we need to
@@ -2217,47 +2248,14 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2217 * 2248 *
2218 * Permission check is handled by selinux_inode_getxattr hook. 2249 * Permission check is handled by selinux_inode_getxattr hook.
2219 */ 2250 */
2220static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) 2251static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
2221{ 2252{
2222 struct inode_security_struct *isec = inode->i_security; 2253 struct inode_security_struct *isec = inode->i_security;
2223 char *context;
2224 unsigned len;
2225 int rc;
2226
2227 if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
2228 rc = -EOPNOTSUPP;
2229 goto out;
2230 }
2231
2232 rc = security_sid_to_context(isec->sid, &context, &len);
2233 if (rc)
2234 goto out;
2235
2236 /* Probe for required buffer size */
2237 if (!buffer || !size) {
2238 rc = len;
2239 goto out_free;
2240 }
2241 2254
2242 if (size < len) { 2255 if (strcmp(name, XATTR_SELINUX_SUFFIX))
2243 rc = -ERANGE; 2256 return -EOPNOTSUPP;
2244 goto out_free;
2245 }
2246 2257
2247 if (err > 0) { 2258 return selinux_getsecurity(isec->sid, buffer, size);
2248 if ((len == err) && !(memcmp(context, buffer, len))) {
2249 /* Don't need to canonicalize value */
2250 rc = err;
2251 goto out_free;
2252 }
2253 memset(buffer, 0, size);
2254 }
2255 memcpy(buffer, context, len);
2256 rc = len;
2257out_free:
2258 kfree(context);
2259out:
2260 return rc;
2261} 2259}
2262 2260
2263static int selinux_inode_setsecurity(struct inode *inode, const char *name, 2261static int selinux_inode_setsecurity(struct inode *inode, const char *name,
@@ -4054,6 +4052,13 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
4054 return ipc_has_perm(ipcp, av); 4052 return ipc_has_perm(ipcp, av);
4055} 4053}
4056 4054
4055static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
4056{
4057 struct ipc_security_struct *isec = ipcp->security;
4058
4059 return selinux_getsecurity(isec->sid, buffer, size);
4060}
4061
4057/* module stacking operations */ 4062/* module stacking operations */
4058static int selinux_register_security (const char *name, struct security_operations *ops) 4063static int selinux_register_security (const char *name, struct security_operations *ops)
4059{ 4064{
@@ -4095,8 +4100,7 @@ static int selinux_getprocattr(struct task_struct *p,
4095 char *name, void *value, size_t size) 4100 char *name, void *value, size_t size)
4096{ 4101{
4097 struct task_security_struct *tsec; 4102 struct task_security_struct *tsec;
4098 u32 sid, len; 4103 u32 sid;
4099 char *context;
4100 int error; 4104 int error;
4101 4105
4102 if (current != p) { 4106 if (current != p) {
@@ -4105,9 +4109,6 @@ static int selinux_getprocattr(struct task_struct *p,
4105 return error; 4109 return error;
4106 } 4110 }
4107 4111
4108 if (!size)
4109 return -ERANGE;
4110
4111 tsec = p->security; 4112 tsec = p->security;
4112 4113
4113 if (!strcmp(name, "current")) 4114 if (!strcmp(name, "current"))
@@ -4124,16 +4125,7 @@ static int selinux_getprocattr(struct task_struct *p,
4124 if (!sid) 4125 if (!sid)
4125 return 0; 4126 return 0;
4126 4127
4127 error = security_sid_to_context(sid, &context, &len); 4128 return selinux_getsecurity(sid, value, size);
4128 if (error)
4129 return error;
4130 if (len > size) {
4131 kfree(context);
4132 return -ERANGE;
4133 }
4134 memcpy(value, context, len);
4135 kfree(context);
4136 return len;
4137} 4129}
4138 4130
4139static int selinux_setprocattr(struct task_struct *p, 4131static int selinux_setprocattr(struct task_struct *p,
@@ -4291,6 +4283,7 @@ static struct security_operations selinux_ops = {
4291 .inode_getxattr = selinux_inode_getxattr, 4283 .inode_getxattr = selinux_inode_getxattr,
4292 .inode_listxattr = selinux_inode_listxattr, 4284 .inode_listxattr = selinux_inode_listxattr,
4293 .inode_removexattr = selinux_inode_removexattr, 4285 .inode_removexattr = selinux_inode_removexattr,
4286 .inode_xattr_getsuffix = selinux_inode_xattr_getsuffix,
4294 .inode_getsecurity = selinux_inode_getsecurity, 4287 .inode_getsecurity = selinux_inode_getsecurity,
4295 .inode_setsecurity = selinux_inode_setsecurity, 4288 .inode_setsecurity = selinux_inode_setsecurity,
4296 .inode_listsecurity = selinux_inode_listsecurity, 4289 .inode_listsecurity = selinux_inode_listsecurity,
@@ -4328,6 +4321,7 @@ static struct security_operations selinux_ops = {
4328 .task_to_inode = selinux_task_to_inode, 4321 .task_to_inode = selinux_task_to_inode,
4329 4322
4330 .ipc_permission = selinux_ipc_permission, 4323 .ipc_permission = selinux_ipc_permission,
4324 .ipc_getsecurity = selinux_ipc_getsecurity,
4331 4325
4332 .msg_msg_alloc_security = selinux_msg_msg_alloc_security, 4326 .msg_msg_alloc_security = selinux_msg_msg_alloc_security,
4333 .msg_msg_free_security = selinux_msg_msg_free_security, 4327 .msg_msg_free_security = selinux_msg_msg_free_security,