aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorMathias Krause <mathias.krause@secunet.com>2015-09-11 03:57:20 -0400
committerSteffen Klassert <steffen.klassert@secunet.com>2015-09-14 04:53:05 -0400
commit04a6b8bfee06e309be7e9ae4527cdab19c081761 (patch)
tree82e72d3ed231222243487b575887c2b974025a6d /net/ipv6
parent93efac3f2e03321129de67a3c0ba53048bb53e31 (diff)
xfrm6: Fix ICMPv6 and MH header checks in _decode_session6
Ensure there's enough data left prior calling pskb_may_pull(). If skb->data was already advanced, we'll call pskb_may_pull() with a negative value converted to unsigned int -- leading to a huge positive value. That won't matter in practice as pskb_may_pull() will likely fail in this case, but it leads to underflow reports on kernels handling such kind of over-/underflows, e.g. a PaX enabled kernel instrumented with the size_overflow plugin. Reported-by: satmd <satmd@lain.at> Reported-and-tested-by: Marcin Jurkowski <marcin1j@gmail.com> Signed-off-by: Mathias Krause <mathias.krause@secunet.com> Cc: PaX Team <pageexec@freemail.hu> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/xfrm6_policy.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 30caa289c5db..f10b9400b6d7 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -178,7 +178,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
178 return; 178 return;
179 179
180 case IPPROTO_ICMPV6: 180 case IPPROTO_ICMPV6:
181 if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) { 181 if (!onlyproto && (nh + offset + 2 < skb->data ||
182 pskb_may_pull(skb, nh + offset + 2 - skb->data))) {
182 u8 *icmp; 183 u8 *icmp;
183 184
184 nh = skb_network_header(skb); 185 nh = skb_network_header(skb);
@@ -192,7 +193,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
192#if IS_ENABLED(CONFIG_IPV6_MIP6) 193#if IS_ENABLED(CONFIG_IPV6_MIP6)
193 case IPPROTO_MH: 194 case IPPROTO_MH:
194 offset += ipv6_optlen(exthdr); 195 offset += ipv6_optlen(exthdr);
195 if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) { 196 if (!onlyproto && (nh + offset + 3 < skb->data ||
197 pskb_may_pull(skb, nh + offset + 3 - skb->data))) {
196 struct ip6_mh *mh; 198 struct ip6_mh *mh;
197 199
198 nh = skb_network_header(skb); 200 nh = skb_network_header(skb);