Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04a6b8bf authored by Mathias Krause's avatar Mathias Krause Committed by Steffen Klassert
Browse files

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: default avatarsatmd <satmd@lain.at>
Reported-and-tested-by: default avatarMarcin Jurkowski <marcin1j@gmail.com>
Signed-off-by: default avatarMathias Krause <mathias.krause@secunet.com>
Cc: PaX Team <pageexec@freemail.hu>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 93efac3f
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -178,7 +178,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
			return;
			return;


		case IPPROTO_ICMPV6:
		case IPPROTO_ICMPV6:
			if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) {
			if (!onlyproto && (nh + offset + 2 < skb->data ||
			    pskb_may_pull(skb, nh + offset + 2 - skb->data))) {
				u8 *icmp;
				u8 *icmp;


				nh = skb_network_header(skb);
				nh = skb_network_header(skb);
@@ -192,7 +193,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
#if IS_ENABLED(CONFIG_IPV6_MIP6)
#if IS_ENABLED(CONFIG_IPV6_MIP6)
		case IPPROTO_MH:
		case IPPROTO_MH:
			offset += ipv6_optlen(exthdr);
			offset += ipv6_optlen(exthdr);
			if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
			if (!onlyproto && (nh + offset + 3 < skb->data ||
			    pskb_may_pull(skb, nh + offset + 3 - skb->data))) {
				struct ip6_mh *mh;
				struct ip6_mh *mh;


				nh = skb_network_header(skb);
				nh = skb_network_header(skb);