diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-25 12:24:53 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-25 12:24:53 -0500 |
| commit | 1b9a3917366028cc451a98dd22e3bcd537d4e5c1 (patch) | |
| tree | d911058720e0a9aeeaf9f407ccdc6fbf4047f47d /security/selinux/hooks.c | |
| parent | 3661f00e2097676847deb01add1a0918044bd816 (diff) | |
| parent | 71e1c784b24a026a490b3de01541fc5ee14ebc09 (diff) | |
Merge branch 'audit.b3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current
* 'audit.b3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current: (22 commits)
[PATCH] fix audit_init failure path
[PATCH] EXPORT_SYMBOL patch for audit_log, audit_log_start, audit_log_end and audit_format
[PATCH] sem2mutex: audit_netlink_sem
[PATCH] simplify audit_free() locking
[PATCH] Fix audit operators
[PATCH] promiscuous mode
[PATCH] Add tty to syscall audit records
[PATCH] add/remove rule update
[PATCH] audit string fields interface + consumer
[PATCH] SE Linux audit events
[PATCH] Minor cosmetic cleanups to the code moved into auditfilter.c
[PATCH] Fix audit record filtering with !CONFIG_AUDITSYSCALL
[PATCH] Fix IA64 success/failure indication in syscall auditing.
[PATCH] Miscellaneous bug and warning fixes
[PATCH] Capture selinux subject/object context information.
[PATCH] Exclude messages by message type
[PATCH] Collect more inode information during syscall processing.
[PATCH] Pass dentry, not just name, in fsnotify creation hooks.
[PATCH] Define new range of userspace messages.
[PATCH] Filter rule comparators
...
Fixed trivial conflict in security/selinux/hooks.c
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 98 |
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 | ||
| 120 | static kmem_cache_t *sel_inode_cache; | 120 | static 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 */ | ||
| 124 | static 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 | |||
| 143 | getsecurity_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 | ||
| 124 | static int task_alloc_security(struct task_struct *task) | 150 | static 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 | ||
| 2239 | static 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 | */ |
| 2220 | static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) | 2251 | static 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; | ||
| 2257 | out_free: | ||
| 2258 | kfree(context); | ||
| 2259 | out: | ||
| 2260 | return rc; | ||
| 2261 | } | 2259 | } |
| 2262 | 2260 | ||
| 2263 | static int selinux_inode_setsecurity(struct inode *inode, const char *name, | 2261 | static 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 | ||
| 4055 | static 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 */ |
| 4058 | static int selinux_register_security (const char *name, struct security_operations *ops) | 4063 | static 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 | ||
| 4139 | static int selinux_setprocattr(struct task_struct *p, | 4131 | static 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, |
