aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorDustin Kirkland <dustin.kirkland@us.ibm.com>2005-11-03 12:15:16 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2006-03-20 14:08:54 -0500
commit8c8570fb8feef2bc166bee75a85748b25cda22d9 (patch)
treeed783d405ea9d5f3d3ccc57fb56c7b7cb2cdfb82 /security/selinux/hooks.c
parentc8edc80c8b8c397c53f4f659a05b9ea6208029bf (diff)
[PATCH] Capture selinux subject/object context information.
This patch extends existing audit records with subject/object context information. Audit records associated with filesystem inodes, ipc, and tasks now contain SELinux label information in the field "subj" if the item is performing the action, or in "obj" if the item is the receiver of an action. These labels are collected via hooks in SELinux and appended to the appropriate record in the audit code. This additional information is required for Common Criteria Labeled Security Protection Profile (LSPP). [AV: fixed kmalloc flags use] [folded leak fixes] [folded cleanup from akpm (kfree(NULL)] [folded audit_inode_context() leak fix] [folded akpm's fix for audit_ipc_perm() definition in case of !CONFIG_AUDIT] Signed-off-by: Dustin Kirkland <dustin.kirkland@us.ibm.com> Signed-off-by: David Woodhouse <dwmw2@infradead.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
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,