diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 66 |
1 files changed, 34 insertions, 32 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5feecb41009d..a03fd74602b4 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -293,28 +293,28 @@ static void superblock_free_security(struct super_block *sb) | |||
293 | 293 | ||
294 | static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) | 294 | static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) |
295 | { | 295 | { |
296 | struct sk_security_struct *ssec; | 296 | struct sk_security_struct *sksec; |
297 | 297 | ||
298 | ssec = kzalloc(sizeof(*ssec), priority); | 298 | sksec = kzalloc(sizeof(*sksec), priority); |
299 | if (!ssec) | 299 | if (!sksec) |
300 | return -ENOMEM; | 300 | return -ENOMEM; |
301 | 301 | ||
302 | ssec->peer_sid = SECINITSID_UNLABELED; | 302 | sksec->peer_sid = SECINITSID_UNLABELED; |
303 | ssec->sid = SECINITSID_UNLABELED; | 303 | sksec->sid = SECINITSID_UNLABELED; |
304 | sk->sk_security = ssec; | 304 | sk->sk_security = sksec; |
305 | 305 | ||
306 | selinux_netlbl_sk_security_reset(ssec); | 306 | selinux_netlbl_sk_security_reset(sksec); |
307 | 307 | ||
308 | return 0; | 308 | return 0; |
309 | } | 309 | } |
310 | 310 | ||
311 | static void sk_free_security(struct sock *sk) | 311 | static void sk_free_security(struct sock *sk) |
312 | { | 312 | { |
313 | struct sk_security_struct *ssec = sk->sk_security; | 313 | struct sk_security_struct *sksec = sk->sk_security; |
314 | 314 | ||
315 | sk->sk_security = NULL; | 315 | sk->sk_security = NULL; |
316 | selinux_netlbl_sk_security_free(ssec); | 316 | selinux_netlbl_sk_security_free(sksec); |
317 | kfree(ssec); | 317 | kfree(sksec); |
318 | } | 318 | } |
319 | 319 | ||
320 | /* The security server must be initialized before | 320 | /* The security server must be initialized before |
@@ -323,7 +323,7 @@ extern int ss_initialized; | |||
323 | 323 | ||
324 | /* The file system's label must be initialized prior to use. */ | 324 | /* The file system's label must be initialized prior to use. */ |
325 | 325 | ||
326 | static char *labeling_behaviors[6] = { | 326 | static const char *labeling_behaviors[6] = { |
327 | "uses xattr", | 327 | "uses xattr", |
328 | "uses transition SIDs", | 328 | "uses transition SIDs", |
329 | "uses task SIDs", | 329 | "uses task SIDs", |
@@ -2999,13 +2999,15 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, | |||
2999 | return file_has_perm(cred, file, av); | 2999 | return file_has_perm(cred, file, av); |
3000 | } | 3000 | } |
3001 | 3001 | ||
3002 | static int default_noexec; | ||
3003 | |||
3002 | static int file_map_prot_check(struct file *file, unsigned long prot, int shared) | 3004 | static int file_map_prot_check(struct file *file, unsigned long prot, int shared) |
3003 | { | 3005 | { |
3004 | const struct cred *cred = current_cred(); | 3006 | const struct cred *cred = current_cred(); |
3005 | int rc = 0; | 3007 | int rc = 0; |
3006 | 3008 | ||
3007 | #ifndef CONFIG_PPC32 | 3009 | if (default_noexec && |
3008 | if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) { | 3010 | (prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) { |
3009 | /* | 3011 | /* |
3010 | * We are making executable an anonymous mapping or a | 3012 | * We are making executable an anonymous mapping or a |
3011 | * private file mapping that will also be writable. | 3013 | * private file mapping that will also be writable. |
@@ -3015,7 +3017,6 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared | |||
3015 | if (rc) | 3017 | if (rc) |
3016 | goto error; | 3018 | goto error; |
3017 | } | 3019 | } |
3018 | #endif | ||
3019 | 3020 | ||
3020 | if (file) { | 3021 | if (file) { |
3021 | /* read access is always possible with a mapping */ | 3022 | /* read access is always possible with a mapping */ |
@@ -3076,8 +3077,8 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
3076 | if (selinux_checkreqprot) | 3077 | if (selinux_checkreqprot) |
3077 | prot = reqprot; | 3078 | prot = reqprot; |
3078 | 3079 | ||
3079 | #ifndef CONFIG_PPC32 | 3080 | if (default_noexec && |
3080 | if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) { | 3081 | (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) { |
3081 | int rc = 0; | 3082 | int rc = 0; |
3082 | if (vma->vm_start >= vma->vm_mm->start_brk && | 3083 | if (vma->vm_start >= vma->vm_mm->start_brk && |
3083 | vma->vm_end <= vma->vm_mm->brk) { | 3084 | vma->vm_end <= vma->vm_mm->brk) { |
@@ -3099,7 +3100,6 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
3099 | if (rc) | 3100 | if (rc) |
3100 | return rc; | 3101 | return rc; |
3101 | } | 3102 | } |
3102 | #endif | ||
3103 | 3103 | ||
3104 | return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED); | 3104 | return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED); |
3105 | } | 3105 | } |
@@ -4002,7 +4002,7 @@ static int selinux_socket_unix_stream_connect(struct socket *sock, | |||
4002 | struct socket *other, | 4002 | struct socket *other, |
4003 | struct sock *newsk) | 4003 | struct sock *newsk) |
4004 | { | 4004 | { |
4005 | struct sk_security_struct *ssec; | 4005 | struct sk_security_struct *sksec; |
4006 | struct inode_security_struct *isec; | 4006 | struct inode_security_struct *isec; |
4007 | struct inode_security_struct *other_isec; | 4007 | struct inode_security_struct *other_isec; |
4008 | struct common_audit_data ad; | 4008 | struct common_audit_data ad; |
@@ -4021,13 +4021,13 @@ static int selinux_socket_unix_stream_connect(struct socket *sock, | |||
4021 | return err; | 4021 | return err; |
4022 | 4022 | ||
4023 | /* connecting socket */ | 4023 | /* connecting socket */ |
4024 | ssec = sock->sk->sk_security; | 4024 | sksec = sock->sk->sk_security; |
4025 | ssec->peer_sid = other_isec->sid; | 4025 | sksec->peer_sid = other_isec->sid; |
4026 | 4026 | ||
4027 | /* server child socket */ | 4027 | /* server child socket */ |
4028 | ssec = newsk->sk_security; | 4028 | sksec = newsk->sk_security; |
4029 | ssec->peer_sid = isec->sid; | 4029 | sksec->peer_sid = isec->sid; |
4030 | err = security_sid_mls_copy(other_isec->sid, ssec->peer_sid, &ssec->sid); | 4030 | err = security_sid_mls_copy(other_isec->sid, sksec->peer_sid, &sksec->sid); |
4031 | 4031 | ||
4032 | return err; | 4032 | return err; |
4033 | } | 4033 | } |
@@ -4190,7 +4190,7 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op | |||
4190 | int err = 0; | 4190 | int err = 0; |
4191 | char *scontext; | 4191 | char *scontext; |
4192 | u32 scontext_len; | 4192 | u32 scontext_len; |
4193 | struct sk_security_struct *ssec; | 4193 | struct sk_security_struct *sksec; |
4194 | struct inode_security_struct *isec; | 4194 | struct inode_security_struct *isec; |
4195 | u32 peer_sid = SECSID_NULL; | 4195 | u32 peer_sid = SECSID_NULL; |
4196 | 4196 | ||
@@ -4198,8 +4198,8 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op | |||
4198 | 4198 | ||
4199 | if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET || | 4199 | if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET || |
4200 | isec->sclass == SECCLASS_TCP_SOCKET) { | 4200 | isec->sclass == SECCLASS_TCP_SOCKET) { |
4201 | ssec = sock->sk->sk_security; | 4201 | sksec = sock->sk->sk_security; |
4202 | peer_sid = ssec->peer_sid; | 4202 | peer_sid = sksec->peer_sid; |
4203 | } | 4203 | } |
4204 | if (peer_sid == SECSID_NULL) { | 4204 | if (peer_sid == SECSID_NULL) { |
4205 | err = -ENOPROTOOPT; | 4205 | err = -ENOPROTOOPT; |
@@ -4266,14 +4266,14 @@ static void selinux_sk_free_security(struct sock *sk) | |||
4266 | 4266 | ||
4267 | static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) | 4267 | static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) |
4268 | { | 4268 | { |
4269 | struct sk_security_struct *ssec = sk->sk_security; | 4269 | struct sk_security_struct *sksec = sk->sk_security; |
4270 | struct sk_security_struct *newssec = newsk->sk_security; | 4270 | struct sk_security_struct *newsksec = newsk->sk_security; |
4271 | 4271 | ||
4272 | newssec->sid = ssec->sid; | 4272 | newsksec->sid = sksec->sid; |
4273 | newssec->peer_sid = ssec->peer_sid; | 4273 | newsksec->peer_sid = sksec->peer_sid; |
4274 | newssec->sclass = ssec->sclass; | 4274 | newsksec->sclass = sksec->sclass; |
4275 | 4275 | ||
4276 | selinux_netlbl_sk_security_reset(newssec); | 4276 | selinux_netlbl_sk_security_reset(newsksec); |
4277 | } | 4277 | } |
4278 | 4278 | ||
4279 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) | 4279 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) |
@@ -5662,6 +5662,8 @@ static __init int selinux_init(void) | |||
5662 | /* Set the security state for the initial task. */ | 5662 | /* Set the security state for the initial task. */ |
5663 | cred_init_security(); | 5663 | cred_init_security(); |
5664 | 5664 | ||
5665 | default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); | ||
5666 | |||
5665 | sel_inode_cache = kmem_cache_create("selinux_inode_security", | 5667 | sel_inode_cache = kmem_cache_create("selinux_inode_security", |
5666 | sizeof(struct inode_security_struct), | 5668 | sizeof(struct inode_security_struct), |
5667 | 0, SLAB_PANIC, NULL); | 5669 | 0, SLAB_PANIC, NULL); |