Message ID | 5a4746774cf7dc8d44598c4595721fba679c481a.1519987422.git.lorenzo.bianconi@redhat.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
Series | [net-next] ipv6: fix access to non-linear packet in ndisc_fill_redirect_hdr_option() | expand |
From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> Date: Fri, 2 Mar 2018 11:53:06 +0100 > Fix the following slab-out-of-bounds kasan report in > ndisc_fill_redirect_hdr_option when the incoming ipv6 packet is not > linear and the accessed data are not in the linear data region of orig_skb ... > Reported-by: Jianlin Shi <jishi@redhat.com> > Reviewed-by: Stefano Brivio <sbrivio@redhat.com> > Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> As a bug fix this should be targetting 'net' not 'net-next'. Furthermore, we need an appropriate Fixes: tag so we know when this problem existed. If you go far back and it seems like the problem has always been there, say so and mention how far back you checked. It also helps to explain exactly how the condition is created ("X creates packet with Y bytes of header space, Z fragments it at byte N, and that's how we end up here with such a packet") because such a description aids understanding and might help suggest alternative (less expensive, cleaner) ways to fix the problem. Thanks.
On Fri, 2018-03-02 at 11:53 +0100, Lorenzo Bianconi wrote: > Fix the following slab-out-of-bounds kasan report in > ndisc_fill_redirect_hdr_option when the incoming ipv6 packet is not > linear and the accessed data are not in the linear data region of orig_skb > > Reported-by: Jianlin Shi <jishi@redhat.com> > Reviewed-by: Stefano Brivio <sbrivio@redhat.com> > Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> > --- > net/ipv6/ndisc.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c > index 0a19ce3a6f7f..afd8c15827cd 100644 > --- a/net/ipv6/ndisc.c > +++ b/net/ipv6/ndisc.c > @@ -1554,7 +1554,8 @@ static void ndisc_fill_redirect_hdr_option(struct sk_buff *skb, > *(opt++) = (rd_len >> 3); > opt += 6; > > - memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8); > + skb_copy_bits(orig_skb, skb_network_offset(orig_skb), opt, > + rd_len - 8); > } Wow, nice catch ! Reviewed-by: Eric Dumazet <edumazet@google.com>
> From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> > Date: Fri, 2 Mar 2018 11:53:06 +0100 > >> Fix the following slab-out-of-bounds kasan report in >> ndisc_fill_redirect_hdr_option when the incoming ipv6 packet is not >> linear and the accessed data are not in the linear data region of orig_skb > ... >> Reported-by: Jianlin Shi <jishi@redhat.com> >> Reviewed-by: Stefano Brivio <sbrivio@redhat.com> >> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> > > As a bug fix this should be targetting 'net' not 'net-next'. > > Furthermore, we need an appropriate Fixes: tag so we know when this > problem existed. > > If you go far back and it seems like the problem has always been > there, say so and mention how far back you checked. Hi Dave, Yes sorry, that is exactly the case. Bisecting the issue, I am able to trigger the kasan report on 4.14 and I have not gone back further. Moreover the issue is much more hard to trigger on net-next (or net) respect to 4.14. > > It also helps to explain exactly how the condition is created > ("X creates packet with Y bytes of header space, Z fragments > it at byte N, and that's how we end up here with such a packet") > because such a description aids understanding and might help > suggest alternative (less expensive, cleaner) ways to fix the > problem. > > Thanks. The test scenario consists of 4 devices (simulated using veth and namespaces): - H0: data sender, connected to LAN0 - H1: data receiver, connected to LAN1 - GW0 and GW1: routers between LAN0 and LAN1. Both of them have an ethernet connection on LAN{0,1} - The default route on H{0,1} is GW0 - using ip command on GW0, set GW1 as next hop for LAN1 from LAN0 - create a ip6ip6 tunnel between H0 and H1 - send 3 concurrent data streams (TCP/UDP/SCTP) from H0 to H1 through ip6ip6 tunnel (buffer size is set to 16K) - while data streams are active flush the route cache on HA multiple times. Regards, Lorenzo
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 0a19ce3a6f7f..afd8c15827cd 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1554,7 +1554,8 @@ static void ndisc_fill_redirect_hdr_option(struct sk_buff *skb, *(opt++) = (rd_len >> 3); opt += 6; - memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8); + skb_copy_bits(orig_skb, skb_network_offset(orig_skb), opt, + rd_len - 8); } void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)