diff options
| -rw-r--r-- | net/ipv6/mcast.c | 19 |
1 files changed, 17 insertions, 2 deletions
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, | |||
| 1087 | 1087 | ||
| 1088 | int igmp6_event_query(struct sk_buff *skb) | 1088 | int igmp6_event_query(struct sk_buff *skb) |
| 1089 | { | 1089 | { |
| 1090 | struct mld2_query *mlh2 = (struct mld2_query *) skb->h.raw; | 1090 | struct mld2_query *mlh2 = NULL; |
| 1091 | struct ifmcaddr6 *ma; | 1091 | struct ifmcaddr6 *ma; |
| 1092 | struct in6_addr *group; | 1092 | struct in6_addr *group; |
| 1093 | unsigned long max_delay; | 1093 | unsigned long max_delay; |
| @@ -1140,6 +1140,13 @@ int igmp6_event_query(struct sk_buff *skb) | |||
| 1140 | /* clear deleted report items */ | 1140 | /* clear deleted report items */ |
| 1141 | mld_clear_delrec(idev); | 1141 | mld_clear_delrec(idev); |
| 1142 | } else if (len >= 28) { | 1142 | } else if (len >= 28) { |
| 1143 | int srcs_offset = sizeof(struct mld2_query) - | ||
| 1144 | sizeof(struct icmp6hdr); | ||
| 1145 | if (!pskb_may_pull(skb, srcs_offset)) { | ||
| 1146 | in6_dev_put(idev); | ||
| 1147 | return -EINVAL; | ||
| 1148 | } | ||
| 1149 | mlh2 = (struct mld2_query *) skb->h.raw; | ||
| 1143 | max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000; | 1150 | max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000; |
| 1144 | if (!max_delay) | 1151 | if (!max_delay) |
| 1145 | max_delay = 1; | 1152 | max_delay = 1; |
| @@ -1156,7 +1163,15 @@ int igmp6_event_query(struct sk_buff *skb) | |||
| 1156 | return 0; | 1163 | return 0; |
| 1157 | } | 1164 | } |
| 1158 | /* mark sources to include, if group & source-specific */ | 1165 | /* mark sources to include, if group & source-specific */ |
| 1159 | mark = mlh2->nsrcs != 0; | 1166 | if (mlh2->nsrcs != 0) { |
| 1167 | if (!pskb_may_pull(skb, srcs_offset + | ||
| 1168 | mlh2->nsrcs * sizeof(struct in6_addr))) { | ||
| 1169 | in6_dev_put(idev); | ||
| 1170 | return -EINVAL; | ||
| 1171 | } | ||
| 1172 | mlh2 = (struct mld2_query *) skb->h.raw; | ||
| 1173 | mark = 1; | ||
| 1174 | } | ||
| 1160 | } else { | 1175 | } else { |
| 1161 | in6_dev_put(idev); | 1176 | in6_dev_put(idev); |
| 1162 | return -EINVAL; | 1177 | return -EINVAL; |
