Skip to content

Commit

Permalink
netfilter: bridge: move pskb_trim_rcsum out of br_nf_check_hbh_len
Browse files Browse the repository at this point in the history
br_nf_check_hbh_len() is a function to check the Hop-by-hop option
header, and shouldn't do pskb_trim_rcsum() there. This patch is to
pass pkt_len out to br_validate_ipv6() and do pskb_trim_rcsum()
after calling br_validate_ipv6() instead.

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>
  • Loading branch information
Xin Long authored and Florian Westphal committed Mar 8, 2023
1 parent a7f1a2f commit 0b24bd7
Showing 1 changed file with 14 additions and 19 deletions.
33 changes: 14 additions & 19 deletions net/bridge/br_netfilter_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@
/* We only check the length. A bridge shouldn't do any hop-by-hop stuff
* anyway
*/
static int br_nf_check_hbh_len(struct sk_buff *skb)
static int br_nf_check_hbh_len(struct sk_buff *skb, u32 *plen)
{
int len, off = sizeof(struct ipv6hdr);
unsigned char *nh;
u32 pkt_len;

if (!pskb_may_pull(skb, off + 8))
return -1;
Expand Down Expand Up @@ -75,6 +74,8 @@ static int br_nf_check_hbh_len(struct sk_buff *skb)
return -1;

if (nh[off] == IPV6_TLV_JUMBO) {
u32 pkt_len;

if (nh[off + 1] != 4 || (off & 3) != 2)
return -1;
pkt_len = ntohl(*(__be32 *)(nh + off + 2));
Expand All @@ -83,10 +84,7 @@ static int br_nf_check_hbh_len(struct sk_buff *skb)
return -1;
if (pkt_len > skb->len - sizeof(struct ipv6hdr))
return -1;
if (pskb_trim_rcsum(skb,
pkt_len + sizeof(struct ipv6hdr)))
return -1;
nh = skb_network_header(skb);
*plen = pkt_len;
}
off += optlen;
len -= optlen;
Expand Down Expand Up @@ -114,22 +112,19 @@ int br_validate_ipv6(struct net *net, struct sk_buff *skb)
goto inhdr_error;

pkt_len = ntohs(hdr->payload_len);
if (hdr->nexthdr == NEXTHDR_HOP && br_nf_check_hbh_len(skb, &pkt_len))
goto drop;

if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) {
if (pkt_len + ip6h_len > skb->len) {
__IP6_INC_STATS(net, idev,
IPSTATS_MIB_INTRUNCATEDPKTS);
goto drop;
}
if (pskb_trim_rcsum(skb, pkt_len + ip6h_len)) {
__IP6_INC_STATS(net, idev,
IPSTATS_MIB_INDISCARDS);
goto drop;
}
hdr = ipv6_hdr(skb);
if (pkt_len + ip6h_len > skb->len) {
__IP6_INC_STATS(net, idev,
IPSTATS_MIB_INTRUNCATEDPKTS);
goto drop;
}
if (hdr->nexthdr == NEXTHDR_HOP && br_nf_check_hbh_len(skb))
if (pskb_trim_rcsum(skb, pkt_len + ip6h_len)) {
__IP6_INC_STATS(net, idev,
IPSTATS_MIB_INDISCARDS);
goto drop;
}

memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
/* No IP options in IPv6 header; however it should be
Expand Down

0 comments on commit 0b24bd7

Please sign in to comment.