aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/mcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r--net/ipv6/mcast.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index c4f2a0ef7489..f15e04ad026e 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -545,8 +545,10 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
545 sock_kfree_s(sk, newpsl, IP6_SFLSIZE(newpsl->sl_max)); 545 sock_kfree_s(sk, newpsl, IP6_SFLSIZE(newpsl->sl_max));
546 goto done; 546 goto done;
547 } 547 }
548 } else 548 } else {
549 newpsl = NULL; 549 newpsl = NULL;
550 (void) ip6_mc_add_src(idev, group, gsf->gf_fmode, 0, NULL, 0);
551 }
550 psl = pmc->sflist; 552 psl = pmc->sflist;
551 if (psl) { 553 if (psl) {
552 (void) ip6_mc_del_src(idev, group, pmc->sfmode, 554 (void) ip6_mc_del_src(idev, group, pmc->sfmode,
@@ -1087,7 +1089,7 @@ static void mld_marksources(struct ifmcaddr6 *pmc, int nsrcs,
1087 1089
1088int igmp6_event_query(struct sk_buff *skb) 1090int igmp6_event_query(struct sk_buff *skb)
1089{ 1091{
1090 struct mld2_query *mlh2 = (struct mld2_query *) skb->h.raw; 1092 struct mld2_query *mlh2 = NULL;
1091 struct ifmcaddr6 *ma; 1093 struct ifmcaddr6 *ma;
1092 struct in6_addr *group; 1094 struct in6_addr *group;
1093 unsigned long max_delay; 1095 unsigned long max_delay;
@@ -1140,6 +1142,13 @@ int igmp6_event_query(struct sk_buff *skb)
1140 /* clear deleted report items */ 1142 /* clear deleted report items */
1141 mld_clear_delrec(idev); 1143 mld_clear_delrec(idev);
1142 } else if (len >= 28) { 1144 } else if (len >= 28) {
1145 int srcs_offset = sizeof(struct mld2_query) -
1146 sizeof(struct icmp6hdr);
1147 if (!pskb_may_pull(skb, srcs_offset)) {
1148 in6_dev_put(idev);
1149 return -EINVAL;
1150 }
1151 mlh2 = (struct mld2_query *) skb->h.raw;
1143 max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000; 1152 max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000;
1144 if (!max_delay) 1153 if (!max_delay)
1145 max_delay = 1; 1154 max_delay = 1;
@@ -1156,7 +1165,15 @@ int igmp6_event_query(struct sk_buff *skb)
1156 return 0; 1165 return 0;
1157 } 1166 }
1158 /* mark sources to include, if group & source-specific */ 1167 /* mark sources to include, if group & source-specific */
1159 mark = mlh2->nsrcs != 0; 1168 if (mlh2->nsrcs != 0) {
1169 if (!pskb_may_pull(skb, srcs_offset +
1170 mlh2->nsrcs * sizeof(struct in6_addr))) {
1171 in6_dev_put(idev);
1172 return -EINVAL;
1173 }
1174 mlh2 = (struct mld2_query *) skb->h.raw;
1175 mark = 1;
1176 }
1160 } else { 1177 } else {
1161 in6_dev_put(idev); 1178 in6_dev_put(idev);
1162 return -EINVAL; 1179 return -EINVAL;