diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 155 |
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 */ |
2891 | static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad) | 2895 | static 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 */ |
2952 | static int selinux_parse_skb_ipv6(struct sk_buff *skb, struct avc_audit_data *ad) | 2976 | static 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 | ||
3008 | static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad, | 3048 | static 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 | ||
3612 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) | 3653 | static 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 | |||
3717 | static 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 | ||
3679 | static void selinux_req_classify_flow(const struct request_sock *req, | 3725 | static 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); |
3836 | out: | 3889 | out: |
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 | ||