On Fri, Mar 03, 2023 at 07:12:37PM -0500, Xin Long wrote: > 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@xxxxxxxxx> Reviewed-by: Simon Horman <simon.horman@xxxxxxxxxxxx> > --- > net/bridge/br_netfilter_ipv6.c | 14 +++++++++----- > 1 file changed, 9 insertions(+), 5 deletions(-) > > diff --git a/net/bridge/br_netfilter_ipv6.c b/net/bridge/br_netfilter_ipv6.c > index 6b07f30675bb..5cd3e4c35123 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 = (u8 *)(ipv6_hdr(skb) + 1); nit: if you need so spin a v2 perhaps it would be worth considering reconciling the type of nh (unsigned char *) with the type of the cast above (u8 *). > + len = (nh[1] + 1) << 3; > + > + if (!pskb_may_pull(skb, off + len)) > + goto bad; > + nh = skb_network_header(skb); > > off += 2; > len -= 2; > -- > 2.39.1 >