diff options
author | Xin Long <lucien.xin@gmail.com> | 2023-03-07 16:31:27 -0500 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2023-03-08 14:25:38 +0100 |
commit | 9ccff83b1322f95da7a74784cf6f47a481e03dc5 (patch) | |
tree | 44249901c8fe197b4e3c763cad66b4534ba04d1e /net/bridge | |
parent | 4386b921857793440ebd4db3d6b70639149c7074 (diff) | |
download | linux-9ccff83b1322f95da7a74784cf6f47a481e03dc5.tar.gz |
netfilter: bridge: call pskb_may_pull in br_nf_check_hbh_len
When checking Hop-by-hop option header, if the option data is in
nonlinear area, it should do pskb_may_pull instead of discarding
the skb as a bad IPv6 packet.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_netfilter_ipv6.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/net/bridge/br_netfilter_ipv6.c b/net/bridge/br_netfilter_ipv6.c index 6b07f30675bb..afd1c718b683 100644 --- a/net/bridge/br_netfilter_ipv6.c +++ b/net/bridge/br_netfilter_ipv6.c @@ -45,14 +45,18 @@ */ static int br_nf_check_hbh_len(struct sk_buff *skb) { - unsigned char *raw = (u8 *)(ipv6_hdr(skb) + 1); + int len, off = sizeof(struct ipv6hdr); + unsigned char *nh; u32 pkt_len; - const unsigned char *nh = skb_network_header(skb); - int off = raw - nh; - int len = (raw[1] + 1) << 3; - if ((raw + len) - skb->data > skb_headlen(skb)) + if (!pskb_may_pull(skb, off + 8)) goto bad; + nh = (unsigned char *)(ipv6_hdr(skb) + 1); + len = (nh[1] + 1) << 3; + + if (!pskb_may_pull(skb, off + len)) + goto bad; + nh = skb_network_header(skb); off += 2; len -= 2; |