diff options
| -rw-r--r-- | security/smack/smack_lsm.c | 22 | 
1 files changed, 16 insertions, 6 deletions
| diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 9ab8097dab7c..340fc30ad85d 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -28,6 +28,7 @@  #include <linux/tcp.h>  #include <linux/udp.h>  #include <linux/dccp.h> +#include <linux/icmpv6.h>  #include <linux/slab.h>  #include <linux/mutex.h>  #include <linux/pipe_fs_i.h> @@ -3896,6 +3897,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)  			sip->sin6_port = th->source;  		break;  	case IPPROTO_UDP: +	case IPPROTO_UDPLITE:  		uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);  		if (uh != NULL)  			sip->sin6_port = uh->source; @@ -3924,15 +3926,19 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)  	struct smack_known *skp = NULL;  	int rc = 0;  	struct smk_audit_info ad; +	u16 family = sk->sk_family;  #ifdef CONFIG_AUDIT  	struct lsm_network_audit net;  #endif  #if IS_ENABLED(CONFIG_IPV6)  	struct sockaddr_in6 sadd;  	int proto; + +	if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) +		family = PF_INET;  #endif /* CONFIG_IPV6 */ -	switch (sk->sk_family) { +	switch (family) {  	case PF_INET:  #ifdef CONFIG_SECURITY_SMACK_NETFILTER  		/* @@ -3950,7 +3956,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)  		 */  		netlbl_secattr_init(&secattr); -		rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); +		rc = netlbl_skbuff_getattr(skb, family, &secattr);  		if (rc == 0)  			skp = smack_from_secattr(&secattr, ssp);  		else @@ -3963,7 +3969,7 @@ access_check:  #endif  #ifdef CONFIG_AUDIT  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); -		ad.a.u.net->family = sk->sk_family; +		ad.a.u.net->family = family;  		ad.a.u.net->netif = skb->skb_iif;  		ipv4_skb_to_auditdata(skb, &ad.a, NULL);  #endif @@ -3977,12 +3983,13 @@ access_check:  		rc = smk_bu_note("IPv4 delivery", skp, ssp->smk_in,  					MAY_WRITE, rc);  		if (rc != 0) -			netlbl_skbuff_err(skb, sk->sk_family, rc, 0); +			netlbl_skbuff_err(skb, family, rc, 0);  		break;  #if IS_ENABLED(CONFIG_IPV6)  	case PF_INET6:  		proto = smk_skb_to_addr_ipv6(skb, &sadd); -		if (proto != IPPROTO_UDP && proto != IPPROTO_TCP) +		if (proto != IPPROTO_UDP && proto != IPPROTO_UDPLITE && +		    proto != IPPROTO_TCP && proto != IPPROTO_DCCP)  			break;  #ifdef SMACK_IPV6_SECMARK_LABELING  		if (skb && skb->secmark != 0) @@ -3993,7 +4000,7 @@ access_check:  			skp = smack_net_ambient;  #ifdef CONFIG_AUDIT  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); -		ad.a.u.net->family = sk->sk_family; +		ad.a.u.net->family = family;  		ad.a.u.net->netif = skb->skb_iif;  		ipv6_skb_to_auditdata(skb, &ad.a, NULL);  #endif /* CONFIG_AUDIT */ @@ -4004,6 +4011,9 @@ access_check:  #ifdef SMACK_IPV6_PORT_LABELING  		rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);  #endif /* SMACK_IPV6_PORT_LABELING */ +		if (rc != 0) +			icmpv6_send(skb, ICMPV6_DEST_UNREACH, +					ICMPV6_ADM_PROHIBITED, 0);  		break;  #endif /* CONFIG_IPV6 */  	} |