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.c155
1 files changed, 104 insertions, 51 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8ab5679a37a3..a29d78d3f44c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -58,6 +58,7 @@
58#include <linux/netlink.h> 58#include <linux/netlink.h>
59#include <linux/tcp.h> 59#include <linux/tcp.h>
60#include <linux/udp.h> 60#include <linux/udp.h>
61#include <linux/dccp.h>
61#include <linux/quota.h> 62#include <linux/quota.h>
62#include <linux/un.h> /* for Unix socket types */ 63#include <linux/un.h> /* for Unix socket types */
63#include <net/af_unix.h> /* for Unix socket types */ 64#include <net/af_unix.h> /* for Unix socket types */
@@ -751,6 +752,8 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
751 return SECCLASS_UDP_SOCKET; 752 return SECCLASS_UDP_SOCKET;
752 else 753 else
753 return SECCLASS_RAWIP_SOCKET; 754 return SECCLASS_RAWIP_SOCKET;
755 case SOCK_DCCP:
756 return SECCLASS_DCCP_SOCKET;
754 default: 757 default:
755 return SECCLASS_RAWIP_SOCKET; 758 return SECCLASS_RAWIP_SOCKET;
756 } 759 }
@@ -1754,7 +1757,8 @@ static inline void flush_unauthorized_files(struct files_struct * files)
1754 get_file(devnull); 1757 get_file(devnull);
1755 } else { 1758 } else {
1756 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR); 1759 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);
1757 if (!devnull) { 1760 if (IS_ERR(devnull)) {
1761 devnull = NULL;
1758 put_unused_fd(fd); 1762 put_unused_fd(fd);
1759 fput(file); 1763 fput(file);
1760 continue; 1764 continue;
@@ -2888,7 +2892,8 @@ static void selinux_task_to_inode(struct task_struct *p,
2888} 2892}
2889 2893
2890/* Returns error only if unable to parse addresses */ 2894/* Returns error only if unable to parse addresses */
2891static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad) 2895static int selinux_parse_skb_ipv4(struct sk_buff *skb,
2896 struct avc_audit_data *ad, u8 *proto)
2892{ 2897{
2893 int offset, ihlen, ret = -EINVAL; 2898 int offset, ihlen, ret = -EINVAL;
2894 struct iphdr _iph, *ih; 2899 struct iphdr _iph, *ih;
@@ -2906,6 +2911,9 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad
2906 ad->u.net.v4info.daddr = ih->daddr; 2911 ad->u.net.v4info.daddr = ih->daddr;
2907 ret = 0; 2912 ret = 0;
2908 2913
2914 if (proto)
2915 *proto = ih->protocol;
2916
2909 switch (ih->protocol) { 2917 switch (ih->protocol) {
2910 case IPPROTO_TCP: { 2918 case IPPROTO_TCP: {
2911 struct tcphdr _tcph, *th; 2919 struct tcphdr _tcph, *th;
@@ -2939,6 +2947,22 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad
2939 break; 2947 break;
2940 } 2948 }
2941 2949
2950 case IPPROTO_DCCP: {
2951 struct dccp_hdr _dccph, *dh;
2952
2953 if (ntohs(ih->frag_off) & IP_OFFSET)
2954 break;
2955
2956 offset += ihlen;
2957 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
2958 if (dh == NULL)
2959 break;
2960
2961 ad->u.net.sport = dh->dccph_sport;
2962 ad->u.net.dport = dh->dccph_dport;
2963 break;
2964 }
2965
2942 default: 2966 default:
2943 break; 2967 break;
2944 } 2968 }
@@ -2949,7 +2973,8 @@ out:
2949#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 2973#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2950 2974
2951/* Returns error only if unable to parse addresses */ 2975/* Returns error only if unable to parse addresses */
2952static int selinux_parse_skb_ipv6(struct sk_buff *skb, struct avc_audit_data *ad) 2976static int selinux_parse_skb_ipv6(struct sk_buff *skb,
2977 struct avc_audit_data *ad, u8 *proto)
2953{ 2978{
2954 u8 nexthdr; 2979 u8 nexthdr;
2955 int ret = -EINVAL, offset; 2980 int ret = -EINVAL, offset;
@@ -2970,6 +2995,9 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, struct avc_audit_data *ad
2970 if (offset < 0) 2995 if (offset < 0)
2971 goto out; 2996 goto out;
2972 2997
2998 if (proto)
2999 *proto = nexthdr;
3000
2973 switch (nexthdr) { 3001 switch (nexthdr) {
2974 case IPPROTO_TCP: { 3002 case IPPROTO_TCP: {
2975 struct tcphdr _tcph, *th; 3003 struct tcphdr _tcph, *th;
@@ -2995,6 +3023,18 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, struct avc_audit_data *ad
2995 break; 3023 break;
2996 } 3024 }
2997 3025
3026 case IPPROTO_DCCP: {
3027 struct dccp_hdr _dccph, *dh;
3028
3029 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
3030 if (dh == NULL)
3031 break;
3032
3033 ad->u.net.sport = dh->dccph_sport;
3034 ad->u.net.dport = dh->dccph_dport;
3035 break;
3036 }
3037
2998 /* includes fragments */ 3038 /* includes fragments */
2999 default: 3039 default:
3000 break; 3040 break;
@@ -3006,13 +3046,13 @@ out:
3006#endif /* IPV6 */ 3046#endif /* IPV6 */
3007 3047
3008static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad, 3048static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
3009 char **addrp, int *len, int src) 3049 char **addrp, int *len, int src, u8 *proto)
3010{ 3050{
3011 int ret = 0; 3051 int ret = 0;
3012 3052
3013 switch (ad->u.net.family) { 3053 switch (ad->u.net.family) {
3014 case PF_INET: 3054 case PF_INET:
3015 ret = selinux_parse_skb_ipv4(skb, ad); 3055 ret = selinux_parse_skb_ipv4(skb, ad, proto);
3016 if (ret || !addrp) 3056 if (ret || !addrp)
3017 break; 3057 break;
3018 *len = 4; 3058 *len = 4;
@@ -3022,7 +3062,7 @@ static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
3022 3062
3023#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3063#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3024 case PF_INET6: 3064 case PF_INET6:
3025 ret = selinux_parse_skb_ipv6(skb, ad); 3065 ret = selinux_parse_skb_ipv6(skb, ad, proto);
3026 if (ret || !addrp) 3066 if (ret || !addrp)
3027 break; 3067 break;
3028 *len = 16; 3068 *len = 16;
@@ -3100,9 +3140,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
3100 if (sock->sk) { 3140 if (sock->sk) {
3101 sksec = sock->sk->sk_security; 3141 sksec = sock->sk->sk_security;
3102 sksec->sid = isec->sid; 3142 sksec->sid = isec->sid;
3103 err = selinux_netlbl_socket_post_create(sock, 3143 err = selinux_netlbl_socket_post_create(sock);
3104 family,
3105 isec->sid);
3106 } 3144 }
3107 3145
3108 return err; 3146 return err;
@@ -3179,7 +3217,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3179 case SECCLASS_UDP_SOCKET: 3217 case SECCLASS_UDP_SOCKET:
3180 node_perm = UDP_SOCKET__NODE_BIND; 3218 node_perm = UDP_SOCKET__NODE_BIND;
3181 break; 3219 break;
3182 3220
3221 case SECCLASS_DCCP_SOCKET:
3222 node_perm = DCCP_SOCKET__NODE_BIND;
3223 break;
3224
3183 default: 3225 default:
3184 node_perm = RAWIP_SOCKET__NODE_BIND; 3226 node_perm = RAWIP_SOCKET__NODE_BIND;
3185 break; 3227 break;
@@ -3217,16 +3259,17 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
3217 return err; 3259 return err;
3218 3260
3219 /* 3261 /*
3220 * If a TCP socket, check name_connect permission for the port. 3262 * If a TCP or DCCP socket, check name_connect permission for the port.
3221 */ 3263 */
3222 isec = SOCK_INODE(sock)->i_security; 3264 isec = SOCK_INODE(sock)->i_security;
3223 if (isec->sclass == SECCLASS_TCP_SOCKET) { 3265 if (isec->sclass == SECCLASS_TCP_SOCKET ||
3266 isec->sclass == SECCLASS_DCCP_SOCKET) {
3224 struct sock *sk = sock->sk; 3267 struct sock *sk = sock->sk;
3225 struct avc_audit_data ad; 3268 struct avc_audit_data ad;
3226 struct sockaddr_in *addr4 = NULL; 3269 struct sockaddr_in *addr4 = NULL;
3227 struct sockaddr_in6 *addr6 = NULL; 3270 struct sockaddr_in6 *addr6 = NULL;
3228 unsigned short snum; 3271 unsigned short snum;
3229 u32 sid; 3272 u32 sid, perm;
3230 3273
3231 if (sk->sk_family == PF_INET) { 3274 if (sk->sk_family == PF_INET) {
3232 addr4 = (struct sockaddr_in *)address; 3275 addr4 = (struct sockaddr_in *)address;
@@ -3245,11 +3288,13 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
3245 if (err) 3288 if (err)
3246 goto out; 3289 goto out;
3247 3290
3291 perm = (isec->sclass == SECCLASS_TCP_SOCKET) ?
3292 TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
3293
3248 AVC_AUDIT_DATA_INIT(&ad,NET); 3294 AVC_AUDIT_DATA_INIT(&ad,NET);
3249 ad.u.net.dport = htons(snum); 3295 ad.u.net.dport = htons(snum);
3250 ad.u.net.family = sk->sk_family; 3296 ad.u.net.family = sk->sk_family;
3251 err = avc_has_perm(isec->sid, sid, isec->sclass, 3297 err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad);
3252 TCP_SOCKET__NAME_CONNECT, &ad);
3253 if (err) 3298 if (err)
3254 goto out; 3299 goto out;
3255 } 3300 }
@@ -3437,7 +3482,13 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
3437 node_perm = NODE__TCP_RECV; 3482 node_perm = NODE__TCP_RECV;
3438 recv_perm = TCP_SOCKET__RECV_MSG; 3483 recv_perm = TCP_SOCKET__RECV_MSG;
3439 break; 3484 break;
3440 3485
3486 case SECCLASS_DCCP_SOCKET:
3487 netif_perm = NETIF__DCCP_RECV;
3488 node_perm = NODE__DCCP_RECV;
3489 recv_perm = DCCP_SOCKET__RECV_MSG;
3490 break;
3491
3441 default: 3492 default:
3442 netif_perm = NETIF__RAWIP_RECV; 3493 netif_perm = NETIF__RAWIP_RECV;
3443 node_perm = NODE__RAWIP_RECV; 3494 node_perm = NODE__RAWIP_RECV;
@@ -3493,7 +3544,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3493 ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]"; 3544 ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]";
3494 ad.u.net.family = family; 3545 ad.u.net.family = family;
3495 3546
3496 err = selinux_parse_skb(skb, &ad, &addrp, &len, 1); 3547 err = selinux_parse_skb(skb, &ad, &addrp, &len, 1, NULL);
3497 if (err) 3548 if (err)
3498 goto out; 3549 goto out;
3499 3550
@@ -3523,25 +3574,16 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
3523 u32 scontext_len; 3574 u32 scontext_len;
3524 struct sk_security_struct *ssec; 3575 struct sk_security_struct *ssec;
3525 struct inode_security_struct *isec; 3576 struct inode_security_struct *isec;
3526 u32 peer_sid = 0; 3577 u32 peer_sid = SECSID_NULL;
3527 3578
3528 isec = SOCK_INODE(sock)->i_security; 3579 isec = SOCK_INODE(sock)->i_security;
3529 3580
3530 /* if UNIX_STREAM check peer_sid, if TCP check dst for labelled sa */ 3581 if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
3531 if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET) { 3582 isec->sclass == SECCLASS_TCP_SOCKET) {
3532 ssec = sock->sk->sk_security; 3583 ssec = sock->sk->sk_security;
3533 peer_sid = ssec->peer_sid; 3584 peer_sid = ssec->peer_sid;
3534 } 3585 }
3535 else if (isec->sclass == SECCLASS_TCP_SOCKET) { 3586 if (peer_sid == SECSID_NULL) {
3536 peer_sid = selinux_netlbl_socket_getpeersec_stream(sock);
3537 if (peer_sid == SECSID_NULL)
3538 peer_sid = selinux_socket_getpeer_stream(sock->sk);
3539 if (peer_sid == SECSID_NULL) {
3540 err = -ENOPROTOOPT;
3541 goto out;
3542 }
3543 }
3544 else {
3545 err = -ENOPROTOOPT; 3587 err = -ENOPROTOOPT;
3546 goto out; 3588 goto out;
3547 } 3589 }
@@ -3573,13 +3615,12 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
3573 u32 peer_secid = SECSID_NULL; 3615 u32 peer_secid = SECSID_NULL;
3574 int err = 0; 3616 int err = 0;
3575 3617
3576 if (sock && (sock->sk->sk_family == PF_UNIX)) 3618 if (sock && sock->sk->sk_family == PF_UNIX)
3577 selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); 3619 selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
3578 else if (skb) { 3620 else if (skb)
3579 peer_secid = selinux_netlbl_socket_getpeersec_dgram(skb); 3621 security_skb_extlbl_sid(skb,
3580 if (peer_secid == SECSID_NULL) 3622 SECINITSID_UNLABELED,
3581 peer_secid = selinux_socket_getpeer_dgram(skb); 3623 &peer_secid);
3582 }
3583 3624
3584 if (peer_secid == SECSID_NULL) 3625 if (peer_secid == SECSID_NULL)
3585 err = -EINVAL; 3626 err = -EINVAL;
@@ -3606,7 +3647,7 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
3606 newssec->sid = ssec->sid; 3647 newssec->sid = ssec->sid;
3607 newssec->peer_sid = ssec->peer_sid; 3648 newssec->peer_sid = ssec->peer_sid;
3608 3649
3609 selinux_netlbl_sk_clone_security(ssec, newssec); 3650 selinux_netlbl_sk_security_clone(ssec, newssec);
3610} 3651}
3611 3652
3612static void selinux_sk_getsecid(struct sock *sk, u32 *secid) 3653static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
@@ -3640,17 +3681,10 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3640 u32 newsid; 3681 u32 newsid;
3641 u32 peersid; 3682 u32 peersid;
3642 3683
3643 newsid = selinux_netlbl_inet_conn_request(skb, sksec->sid); 3684 security_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &peersid);
3644 if (newsid != SECSID_NULL) {
3645 req->secid = newsid;
3646 return 0;
3647 }
3648
3649 err = selinux_xfrm_decode_session(skb, &peersid, 0);
3650 BUG_ON(err);
3651
3652 if (peersid == SECSID_NULL) { 3685 if (peersid == SECSID_NULL) {
3653 req->secid = sksec->sid; 3686 req->secid = sksec->sid;
3687 req->peer_secid = SECSID_NULL;
3654 return 0; 3688 return 0;
3655 } 3689 }
3656 3690
@@ -3659,6 +3693,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3659 return err; 3693 return err;
3660 3694
3661 req->secid = newsid; 3695 req->secid = newsid;
3696 req->peer_secid = peersid;
3662 return 0; 3697 return 0;
3663} 3698}
3664 3699
@@ -3668,12 +3703,23 @@ static void selinux_inet_csk_clone(struct sock *newsk,
3668 struct sk_security_struct *newsksec = newsk->sk_security; 3703 struct sk_security_struct *newsksec = newsk->sk_security;
3669 3704
3670 newsksec->sid = req->secid; 3705 newsksec->sid = req->secid;
3706 newsksec->peer_sid = req->peer_secid;
3671 /* NOTE: Ideally, we should also get the isec->sid for the 3707 /* NOTE: Ideally, we should also get the isec->sid for the
3672 new socket in sync, but we don't have the isec available yet. 3708 new socket in sync, but we don't have the isec available yet.
3673 So we will wait until sock_graft to do it, by which 3709 So we will wait until sock_graft to do it, by which
3674 time it will have been created and available. */ 3710 time it will have been created and available. */
3675 3711
3676 selinux_netlbl_sk_security_init(newsksec, req->rsk_ops->family); 3712 /* We don't need to take any sort of lock here as we are the only
3713 * thread with access to newsksec */
3714 selinux_netlbl_sk_security_reset(newsksec, req->rsk_ops->family);
3715}
3716
3717static void selinux_inet_conn_established(struct sock *sk,
3718 struct sk_buff *skb)
3719{
3720 struct sk_security_struct *sksec = sk->sk_security;
3721
3722 security_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &sksec->peer_sid);
3677} 3723}
3678 3724
3679static void selinux_req_classify_flow(const struct request_sock *req, 3725static void selinux_req_classify_flow(const struct request_sock *req,
@@ -3756,7 +3802,13 @@ static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *
3756 node_perm = NODE__TCP_SEND; 3802 node_perm = NODE__TCP_SEND;
3757 send_perm = TCP_SOCKET__SEND_MSG; 3803 send_perm = TCP_SOCKET__SEND_MSG;
3758 break; 3804 break;
3759 3805
3806 case SECCLASS_DCCP_SOCKET:
3807 netif_perm = NETIF__DCCP_SEND;
3808 node_perm = NODE__DCCP_SEND;
3809 send_perm = DCCP_SOCKET__SEND_MSG;
3810 break;
3811
3760 default: 3812 default:
3761 netif_perm = NETIF__RAWIP_SEND; 3813 netif_perm = NETIF__RAWIP_SEND;
3762 node_perm = NODE__RAWIP_SEND; 3814 node_perm = NODE__RAWIP_SEND;
@@ -3807,6 +3859,7 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3807 struct avc_audit_data ad; 3859 struct avc_audit_data ad;
3808 struct net_device *dev = (struct net_device *)out; 3860 struct net_device *dev = (struct net_device *)out;
3809 struct sk_security_struct *sksec; 3861 struct sk_security_struct *sksec;
3862 u8 proto;
3810 3863
3811 sk = skb->sk; 3864 sk = skb->sk;
3812 if (!sk) 3865 if (!sk)
@@ -3818,7 +3871,7 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3818 ad.u.net.netif = dev->name; 3871 ad.u.net.netif = dev->name;
3819 ad.u.net.family = family; 3872 ad.u.net.family = family;
3820 3873
3821 err = selinux_parse_skb(skb, &ad, &addrp, &len, 0); 3874 err = selinux_parse_skb(skb, &ad, &addrp, &len, 0, &proto);
3822 if (err) 3875 if (err)
3823 goto out; 3876 goto out;
3824 3877
@@ -3832,7 +3885,7 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3832 if (err) 3885 if (err)
3833 goto out; 3886 goto out;
3834 3887
3835 err = selinux_xfrm_postroute_last(sksec->sid, skb, &ad); 3888 err = selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto);
3836out: 3889out:
3837 return err ? NF_DROP : NF_ACCEPT; 3890 return err ? NF_DROP : NF_ACCEPT;
3838} 3891}
@@ -4738,6 +4791,7 @@ static struct security_operations selinux_ops = {
4738 .sock_graft = selinux_sock_graft, 4791 .sock_graft = selinux_sock_graft,
4739 .inet_conn_request = selinux_inet_conn_request, 4792 .inet_conn_request = selinux_inet_conn_request,
4740 .inet_csk_clone = selinux_inet_csk_clone, 4793 .inet_csk_clone = selinux_inet_csk_clone,
4794 .inet_conn_established = selinux_inet_conn_established,
4741 .req_classify_flow = selinux_req_classify_flow, 4795 .req_classify_flow = selinux_req_classify_flow,
4742 4796
4743#ifdef CONFIG_SECURITY_NETWORK_XFRM 4797#ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -4750,7 +4804,6 @@ static struct security_operations selinux_ops = {
4750 .xfrm_state_delete_security = selinux_xfrm_state_delete, 4804 .xfrm_state_delete_security = selinux_xfrm_state_delete,
4751 .xfrm_policy_lookup = selinux_xfrm_policy_lookup, 4805 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,
4752 .xfrm_state_pol_flow_match = selinux_xfrm_state_pol_flow_match, 4806 .xfrm_state_pol_flow_match = selinux_xfrm_state_pol_flow_match,
4753 .xfrm_flow_state_match = selinux_xfrm_flow_state_match,
4754 .xfrm_decode_session = selinux_xfrm_decode_session, 4807 .xfrm_decode_session = selinux_xfrm_decode_session,
4755#endif 4808#endif
4756 4809