[Feature][ZXW-65]merged P49 base code

Change-Id: I3e09c0c3d47483bc645f02310380ecb7fc6f4041
diff --git a/ap/os/linux/linux-3.4.x/net/ipv6/ip6_output.c b/ap/os/linux/linux-3.4.x/net/ipv6/ip6_output.c
index daadf4c..97aca44 100755
--- a/ap/os/linux/linux-3.4.x/net/ipv6/ip6_output.c
+++ b/ap/os/linux/linux-3.4.x/net/ipv6/ip6_output.c
@@ -563,7 +563,7 @@
 
 int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 {
-	u16 offset = sizeof(struct ipv6hdr);
+	unsigned int offset = sizeof(struct ipv6hdr);//CVE-2017-7542(BDSA-2017-0992)
 	//struct ipv6_opt_hdr *exthdr =//CVE-2017-9074
 				//(struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
 	unsigned int packet_len = skb->tail - skb->network_header;
@@ -573,6 +573,7 @@
 	//while (offset + 1 <= packet_len) {//CVE-2017-9074
 	while (offset <= packet_len) {
 		struct ipv6_opt_hdr *exthdr;//CVE-2017-9074
+		unsigned int len;
 		switch (**nexthdr) {
 
 		case NEXTHDR_HOP:
@@ -598,7 +599,11 @@
 			return -EINVAL;//CVE-2017-9074
 		exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
 						 offset);
-		offset += ipv6_optlen(exthdr);
+		//CVE-2017-7542(BDSA-2017-0992)
+		len = ipv6_optlen(exthdr);
+		if (len + offset >= IPV6_MAXPLEN)
+			return -EINVAL;
+		offset += len;
 		*nexthdr = &exthdr->nexthdr;//CVE-2017-9074
 	}
 
@@ -1430,6 +1435,11 @@
 			 */
 			alloclen += sizeof(struct frag_hdr);
 
+			copy = datalen - transhdrlen - fraggap; //CVE-2017-9242(BDSA-2017-1000)
+			if (copy < 0) {
+				err = -EINVAL;
+				goto error;
+			}
 			if (transhdrlen) {
 				skb = sock_alloc_send_skb(sk,
 						alloclen + hh_len,
@@ -1481,13 +1491,9 @@
 				data += fraggap;
 				pskb_trim_unique(skb_prev, maxfraglen);
 			}
-			copy = datalen - transhdrlen - fraggap;
-
-			if (copy < 0) {
-				err = -EINVAL;
-				kfree_skb(skb);
-				goto error;
-			} else if (copy > 0 && getfrag(from, data + transhdrlen, offset, copy, fraggap, skb) < 0) {
+			if (copy > 0 &&
+			    getfrag(from, data + transhdrlen, offset,
+				    copy, fraggap, skb) < 0) { //CVE-2017-9242(BDSA-2017-1000)
 				err = -EFAULT;
 				kfree_skb(skb);
 				goto error;
diff --git a/ap/os/linux/linux-3.4.x/net/ipv6/ipv6_sockglue.c b/ap/os/linux/linux-3.4.x/net/ipv6/ipv6_sockglue.c
index ba074eb..8ad6b2f 100755
--- a/ap/os/linux/linux-3.4.x/net/ipv6/ipv6_sockglue.c
+++ b/ap/os/linux/linux-3.4.x/net/ipv6/ipv6_sockglue.c
@@ -67,6 +67,8 @@
 		return -ENOPROTOOPT;
 
 	new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
+	if (sel >= 0 && !new_ra) //CVE-2019-12378(BDSA-2019-1655)
+		return -ENOMEM;
 
 	write_lock_bh(&ip6_ra_lock);
 	for (rap = &ip6_ra_chain; (ra=*rap) != NULL; rap = &ra->next) {
@@ -150,6 +152,13 @@
 
 	lock_sock(sk);
 
+	/* BDSA-2022-2918(CVE-2022-3524) */
+	/* Another thread has converted the socket into IPv4 with
+	 * IPV6_ADDRFORM concurrently.
+	 */
+	if (unlikely(sk->sk_family != AF_INET6))
+		goto unlock;
+
 	switch (optname) {
 
 	case IPV6_ADDRFORM:
@@ -854,6 +863,7 @@
 		break;
 	}
 
+unlock: //BDSA-2022-2918(CVE-2022-3524)
 	release_sock(sk);
 
 	return retv;
diff --git a/ap/os/linux/linux-3.4.x/net/ipv6/udp.c b/ap/os/linux/linux-3.4.x/net/ipv6/udp.c
index 0bf27fb..18328b5 100755
--- a/ap/os/linux/linux-3.4.x/net/ipv6/udp.c
+++ b/ap/os/linux/linux-3.4.x/net/ipv6/udp.c
@@ -718,7 +718,8 @@
 }
 
 extern void fast_sk_add_ct(struct sk_buff * skb,struct sock *sk);
-
+int udp6_zero_csum_ctrl = 1;
+module_param(udp6_zero_csum_ctrl,int,0644);
 int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		   int proto)
 {
@@ -759,7 +760,7 @@
 		}
 	}
 
-	if (udp6_csum_init(skb, uh, proto))
+	if (!(udp6_zero_csum_ctrl && ((IPPROTO_UDP == proto)&&(0 == uh->check))) && udp6_csum_init(skb, uh, proto))
 		goto discard;
 
 	/*