summaryrefslogtreecommitdiffstats
path: root/net/ipv6/xfrm6_policy.c
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2014-12-08 07:56:18 +0100
committerSteffen Klassert <steffen.klassert@secunet.com>2014-12-08 07:56:18 +0100
commitf855691975bb06373a98711e4cfe2c224244b536 (patch)
tree9469cc24b2824cea15c6a61884087359f22df6fc /net/ipv6/xfrm6_policy.c
parentxfrm6: Fix transport header offset in _decode_session6. (diff)
downloadlinux-f855691975bb06373a98711e4cfe2c224244b536.tar.xz
linux-f855691975bb06373a98711e4cfe2c224244b536.zip
xfrm6: Fix the nexthdr offset in _decode_session6.
xfrm_decode_session() was originally designed for the usage in the receive path where the correct nexthdr offset is stored in IP6CB(skb)->nhoff. Over time this function spread to code that is used in the output path (netfilter, vti) where IP6CB(skb)->nhoff is not set. As a result, we get a wrong nexthdr and the upper layer flow informations are wrong. This can leed to incorrect policy lookups. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/ipv6/xfrm6_policy.c')
-rw-r--r--net/ipv6/xfrm6_policy.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index aa48302f00a1..48bf5a06847b 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -134,8 +134,14 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
u16 offset = sizeof(*hdr);
struct ipv6_opt_hdr *exthdr;
const unsigned char *nh = skb_network_header(skb);
- u8 nexthdr = nh[IP6CB(skb)->nhoff];
+ u16 nhoff = IP6CB(skb)->nhoff;
int oif = 0;
+ u8 nexthdr;
+
+ if (!nhoff)
+ nhoff = offsetof(struct ipv6hdr, nexthdr);
+
+ nexthdr = nh[nhoff];
if (skb_dst(skb))
oif = skb_dst(skb)->dev->ifindex;