Xin Long <lucien.xin@xxxxxxxxx> writes: > 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: Aaron Conole <aconole@xxxxxxxxxx> > 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); > + len = (nh[1] + 1) << 3; > + > + if (!pskb_may_pull(skb, off + len)) > + goto bad; > + nh = skb_network_header(skb); > > off += 2; > len -= 2;