diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 33028b3b19ce..2a6bbb921e1e 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -12,6 +12,8 @@ | |||
12 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> | 12 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> |
13 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 13 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. |
14 | * <dgoeddel@trustedcs.com> | 14 | * <dgoeddel@trustedcs.com> |
15 | * Copyright (C) 2006 Hewlett-Packard Development Company, L.P. | ||
16 | * Paul Moore, <paul.moore@hp.com> | ||
15 | * | 17 | * |
16 | * This program is free software; you can redistribute it and/or modify | 18 | * This program is free software; you can redistribute it and/or modify |
17 | * it under the terms of the GNU General Public License version 2, | 19 | * it under the terms of the GNU General Public License version 2, |
@@ -74,6 +76,7 @@ | |||
74 | #include "objsec.h" | 76 | #include "objsec.h" |
75 | #include "netif.h" | 77 | #include "netif.h" |
76 | #include "xfrm.h" | 78 | #include "xfrm.h" |
79 | #include "selinux_netlabel.h" | ||
77 | 80 | ||
78 | #define XATTR_SELINUX_SUFFIX "selinux" | 81 | #define XATTR_SELINUX_SUFFIX "selinux" |
79 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX | 82 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX |
@@ -2395,6 +2398,7 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t | |||
2395 | 2398 | ||
2396 | static int selinux_file_permission(struct file *file, int mask) | 2399 | static int selinux_file_permission(struct file *file, int mask) |
2397 | { | 2400 | { |
2401 | int rc; | ||
2398 | struct inode *inode = file->f_dentry->d_inode; | 2402 | struct inode *inode = file->f_dentry->d_inode; |
2399 | 2403 | ||
2400 | if (!mask) { | 2404 | if (!mask) { |
@@ -2406,8 +2410,12 @@ static int selinux_file_permission(struct file *file, int mask) | |||
2406 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) | 2410 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) |
2407 | mask |= MAY_APPEND; | 2411 | mask |= MAY_APPEND; |
2408 | 2412 | ||
2409 | return file_has_perm(current, file, | 2413 | rc = file_has_perm(current, file, |
2410 | file_mask_to_av(inode->i_mode, mask)); | 2414 | file_mask_to_av(inode->i_mode, mask)); |
2415 | if (rc) | ||
2416 | return rc; | ||
2417 | |||
2418 | return selinux_netlbl_inode_permission(inode, mask); | ||
2411 | } | 2419 | } |
2412 | 2420 | ||
2413 | static int selinux_file_alloc_security(struct file *file) | 2421 | static int selinux_file_alloc_security(struct file *file) |
@@ -3058,9 +3066,10 @@ out: | |||
3058 | return err; | 3066 | return err; |
3059 | } | 3067 | } |
3060 | 3068 | ||
3061 | static void selinux_socket_post_create(struct socket *sock, int family, | 3069 | static int selinux_socket_post_create(struct socket *sock, int family, |
3062 | int type, int protocol, int kern) | 3070 | int type, int protocol, int kern) |
3063 | { | 3071 | { |
3072 | int err = 0; | ||
3064 | struct inode_security_struct *isec; | 3073 | struct inode_security_struct *isec; |
3065 | struct task_security_struct *tsec; | 3074 | struct task_security_struct *tsec; |
3066 | struct sk_security_struct *sksec; | 3075 | struct sk_security_struct *sksec; |
@@ -3077,9 +3086,12 @@ static void selinux_socket_post_create(struct socket *sock, int family, | |||
3077 | if (sock->sk) { | 3086 | if (sock->sk) { |
3078 | sksec = sock->sk->sk_security; | 3087 | sksec = sock->sk->sk_security; |
3079 | sksec->sid = isec->sid; | 3088 | sksec->sid = isec->sid; |
3089 | err = selinux_netlbl_socket_post_create(sock, | ||
3090 | family, | ||
3091 | isec->sid); | ||
3080 | } | 3092 | } |
3081 | 3093 | ||
3082 | return; | 3094 | return err; |
3083 | } | 3095 | } |
3084 | 3096 | ||
3085 | /* Range of port numbers used to automatically bind. | 3097 | /* Range of port numbers used to automatically bind. |
@@ -3260,7 +3272,13 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock) | |||
3260 | static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, | 3272 | static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, |
3261 | int size) | 3273 | int size) |
3262 | { | 3274 | { |
3263 | return socket_has_perm(current, sock, SOCKET__WRITE); | 3275 | int rc; |
3276 | |||
3277 | rc = socket_has_perm(current, sock, SOCKET__WRITE); | ||
3278 | if (rc) | ||
3279 | return rc; | ||
3280 | |||
3281 | return selinux_netlbl_inode_permission(SOCK_INODE(sock), MAY_WRITE); | ||
3264 | } | 3282 | } |
3265 | 3283 | ||
3266 | static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, | 3284 | static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, |
@@ -3468,6 +3486,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3468 | if (err) | 3486 | if (err) |
3469 | goto out; | 3487 | goto out; |
3470 | 3488 | ||
3489 | err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad); | ||
3490 | if (err) | ||
3491 | goto out; | ||
3492 | |||
3471 | err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad); | 3493 | err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad); |
3472 | out: | 3494 | out: |
3473 | return err; | 3495 | return err; |
@@ -3491,8 +3513,9 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op | |||
3491 | peer_sid = ssec->peer_sid; | 3513 | peer_sid = ssec->peer_sid; |
3492 | } | 3514 | } |
3493 | else if (isec->sclass == SECCLASS_TCP_SOCKET) { | 3515 | else if (isec->sclass == SECCLASS_TCP_SOCKET) { |
3494 | peer_sid = selinux_socket_getpeer_stream(sock->sk); | 3516 | peer_sid = selinux_netlbl_socket_getpeersec_stream(sock); |
3495 | 3517 | if (peer_sid == SECSID_NULL) | |
3518 | peer_sid = selinux_socket_getpeer_stream(sock->sk); | ||
3496 | if (peer_sid == SECSID_NULL) { | 3519 | if (peer_sid == SECSID_NULL) { |
3497 | err = -ENOPROTOOPT; | 3520 | err = -ENOPROTOOPT; |
3498 | goto out; | 3521 | goto out; |
@@ -3532,8 +3555,11 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff * | |||
3532 | 3555 | ||
3533 | if (sock && (sock->sk->sk_family == PF_UNIX)) | 3556 | if (sock && (sock->sk->sk_family == PF_UNIX)) |
3534 | selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); | 3557 | selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); |
3535 | else if (skb) | 3558 | else if (skb) { |
3536 | peer_secid = selinux_socket_getpeer_dgram(skb); | 3559 | peer_secid = selinux_netlbl_socket_getpeersec_dgram(skb); |
3560 | if (peer_secid == SECSID_NULL) | ||
3561 | peer_secid = selinux_socket_getpeer_dgram(skb); | ||
3562 | } | ||
3537 | 3563 | ||
3538 | if (peer_secid == SECSID_NULL) | 3564 | if (peer_secid == SECSID_NULL) |
3539 | err = -EINVAL; | 3565 | err = -EINVAL; |
@@ -3578,6 +3604,8 @@ void selinux_sock_graft(struct sock* sk, struct socket *parent) | |||
3578 | struct sk_security_struct *sksec = sk->sk_security; | 3604 | struct sk_security_struct *sksec = sk->sk_security; |
3579 | 3605 | ||
3580 | isec->sid = sksec->sid; | 3606 | isec->sid = sksec->sid; |
3607 | |||
3608 | selinux_netlbl_sock_graft(sk, parent); | ||
3581 | } | 3609 | } |
3582 | 3610 | ||
3583 | int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, | 3611 | int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, |
@@ -3585,9 +3613,15 @@ int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
3585 | { | 3613 | { |
3586 | struct sk_security_struct *sksec = sk->sk_security; | 3614 | struct sk_security_struct *sksec = sk->sk_security; |
3587 | int err; | 3615 | int err; |
3588 | u32 newsid = 0; | 3616 | u32 newsid; |
3589 | u32 peersid; | 3617 | u32 peersid; |
3590 | 3618 | ||
3619 | newsid = selinux_netlbl_inet_conn_request(skb, sksec->sid); | ||
3620 | if (newsid != SECSID_NULL) { | ||
3621 | req->secid = newsid; | ||
3622 | return 0; | ||
3623 | } | ||
3624 | |||
3591 | err = selinux_xfrm_decode_session(skb, &peersid, 0); | 3625 | err = selinux_xfrm_decode_session(skb, &peersid, 0); |
3592 | BUG_ON(err); | 3626 | BUG_ON(err); |
3593 | 3627 | ||