From: Yan Zheng <yanzheng@21cn.com>
Date: Mon, 31 Oct 2005 12:09:45 +0000 (+0800)
Subject: [MCAST] IPv6: Check packet size when process Multicast
X-Git-Tag: firefly_0821_release~39876^2~46^2
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=97300b5fdfe28c6edae926926f9467a27cf5889c;p=firefly-linux-kernel-4.4.55.git

[MCAST] IPv6: Check packet size when process Multicast

Signed-off-by: Yan Zheng <yanzheng@21cn.com
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---

diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index c4f2a0ef7489..966b2372aaab 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1087,7 +1087,7 @@ static void mld_marksources(struct ifmcaddr6 *pmc, int nsrcs,
 
 int igmp6_event_query(struct sk_buff *skb)
 {
-	struct mld2_query *mlh2 = (struct mld2_query *) skb->h.raw;
+	struct mld2_query *mlh2 = NULL;
 	struct ifmcaddr6 *ma;
 	struct in6_addr *group;
 	unsigned long max_delay;
@@ -1140,6 +1140,13 @@ int igmp6_event_query(struct sk_buff *skb)
 		/* clear deleted report items */
 		mld_clear_delrec(idev);
 	} else if (len >= 28) {
+		int srcs_offset = sizeof(struct mld2_query) - 
+				  sizeof(struct icmp6hdr);
+		if (!pskb_may_pull(skb, srcs_offset)) {
+			in6_dev_put(idev);
+			return -EINVAL;
+		}
+		mlh2 = (struct mld2_query *) skb->h.raw;
 		max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000;
 		if (!max_delay)
 			max_delay = 1;
@@ -1156,7 +1163,15 @@ int igmp6_event_query(struct sk_buff *skb)
 			return 0;
 		}
 		/* mark sources to include, if group & source-specific */
-		mark = mlh2->nsrcs != 0;
+		if (mlh2->nsrcs != 0) {
+			if (!pskb_may_pull(skb, srcs_offset + 
+				mlh2->nsrcs * sizeof(struct in6_addr))) {
+				in6_dev_put(idev);
+				return -EINVAL;
+			}
+			mlh2 = (struct mld2_query *) skb->h.raw;
+			mark = 1;
+		}
 	} else {
 		in6_dev_put(idev);
 		return -EINVAL;