diff options
author | Steffen Klassert <steffen.klassert@secunet.com> | 2014-12-08 07:56:18 +0100 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2014-12-08 07:56:18 +0100 |
commit | f855691975bb06373a98711e4cfe2c224244b536 (patch) | |
tree | 9469cc24b2824cea15c6a61884087359f22df6fc /net/ipv6 | |
parent | de3b7a06dfe15bda3e66a52285d422b954bb4832 (diff) |
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')
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 8 |
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; |