diff options
author | Yan Zheng <yanzheng@21cn.com> | 2005-10-31 07:09:45 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2005-10-31 19:52:03 -0500 |
commit | 97300b5fdfe28c6edae926926f9467a27cf5889c (patch) | |
tree | 5a28ee8ff8fbddb44ed3f8b5e3d37c0439af1608 /net/ipv6/mcast.c | |
parent | edc9e81917157d1e73bf081d4fbcad7c34d32783 (diff) |
[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>
Diffstat (limited to 'net/ipv6/mcast.c')
-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; |