From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f54.google.com ([74.125.83.54]:41452 "EHLO mail-pg0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752002AbeCWNY4 (ORCPT ); Fri, 23 Mar 2018 09:24:56 -0400 Received: by mail-pg0-f54.google.com with SMTP id m24so4559690pgv.8 for ; Fri, 23 Mar 2018 06:24:56 -0700 (PDT) Subject: Re: [PATCH net] ipv6: the entire IPv6 header chain must fit the first fragment To: Paolo Abeni , netdev@vger.kernel.org Cc: "David S. Miller" , David Ahern , syzbot , syzkaller-bugs@googlegroups.com References: <32b7e42bdb00fa809e7a04eedeae43004abe07eb.1521810295.git.pabeni@redhat.com> From: Eric Dumazet Message-ID: <5addc8ee-5faa-161f-6c91-f5481ddb0400@gmail.com> Date: Fri, 23 Mar 2018 06:24:54 -0700 MIME-Version: 1.0 In-Reply-To: <32b7e42bdb00fa809e7a04eedeae43004abe07eb.1521810295.git.pabeni@redhat.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: netdev-owner@vger.kernel.org List-ID: On 03/23/2018 06:05 AM, Paolo Abeni wrote: > While building ipv6 datagram we currently allow arbitrary large > extheaders, even beyond pmtu size. The syzbot has found a way > to exploit the above to trigger the following splat: > ... > As stated by RFC 7112 section 5: > > When a host fragments an IPv6 datagram, it MUST include the entire > IPv6 Header Chain in the First Fragment. > > So this patch addresses the issue dropping datagrams with excessive > extheader length. It also updates the error path to report to the > calling socket nonnegative pmtu values. > > The issue apparently predates git history. > > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") > Reported-by: syzbot+91e6f9932ff122fa4410@syzkaller.appspotmail.com > Signed-off-by: Paolo Abeni > --- > net/ipv6/ip6_output.c | 18 ++++++++++++++---- > 1 file changed, 14 insertions(+), 4 deletions(-) > > - sizeof(struct ipv6hdr)); > + /* with large extheader pmtu can be negative, cap the reported > + * value to 0, since it is unsigned > + */ > + pmtu = mtu + sizeof(struct ipv6hdr) > headersize ? > + mtu - headersize + sizeof(struct ipv6hdr) : 0; I would suggest : pmtu = max_t(int, mtu - headersize + sizeof(struct ipv6hdr), 0); And you can omit the comment, since the max_t() intent is obvious. Thanks for working on this syzbot report.