From patchwork Wed Aug 2 07:36:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 129698 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9f41:0:b0:3e4:2afc:c1 with SMTP id v1csp298967vqx; Wed, 2 Aug 2023 01:27:52 -0700 (PDT) X-Google-Smtp-Source: APBJJlFrCTU4f3swQYctYstd5galaqR3O128LIlZDfbQfzRNb1c3/9s7ruwRhPEvy76vHOpQ62+m X-Received: by 2002:a17:902:c94e:b0:1b6:a37a:65b7 with SMTP id i14-20020a170902c94e00b001b6a37a65b7mr19500652pla.23.1690964872277; Wed, 02 Aug 2023 01:27:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690964872; cv=none; d=google.com; s=arc-20160816; b=teFjC3KDaYQxNkZhl4A8NNo9yw0CjJpfv5Ro3r1mkMOuWpTOGAK5AK2MGYS8Nep8uK m9wACIDE+vva+74kv3cvai6Is+lsWAgtaUfqSGCMOEEvHPw6M75nSZdhzyoWmDkjSzH2 XiApumE4Y+i4Kv9NTXQ63GJ8AmDVAr3/mGemzPfJji3aJv7X+Sbvmq6NE2shTbV1qXud gLx8CAP2XYTCYuuk/ZAwLGP0Whtt7yXfQiOkEyxoeFyp9OCXYDA6IxEhxnKrYtWu0awo vRFlxW+RqmSOPTq1rCzUYVic4q/DYEHYSCUA/unfBb0iV/wlHpYBVzNM9I+cSGD1+7us G2zA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:message-id:date:content-id:mime-version:subject :cc:to:from:organization:dkim-signature; bh=Af46NJKmEBmqy5H958slGnADxdkvZPSFCpD9BIDom1E=; fh=sNMMWQTQQL4jS23WvYxwAJ6nk8/wHFpQy0iwPKo/4jY=; b=La4RR7kvhbc4xEwoCCOlhNhzZsmUFHhinWiQF+Nc9WQLwwChmZwO8jktHzI0utyJIG y3t5q5N8q+QPF2gSf4bDMW4SY4wZYYzWniTZjJVv8dbIOXP2z6OX2Uxou/sgepo0/TVc BXwbQDqIX+dNycJHW8jKE6l9dx/mYvqs1EHNAXpOIr9n9TcdfOD3iD+OMemHb6CB8dV9 +DECEY3BBmI4bG3EySvYK7v8YgLTVEAjKg2FGQ47f1s6Av9IftI9KaftHymJJF2nQ7rS 0X4hsZjBjx2w4pi5/MN3+anjhjPRpAxWIbJmNmdD0qU60SElAUOY2phlgTX1mS1C7the zUYw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=K8ktEoXk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p18-20020a170902e75200b001b8ae69289dsi2315113plf.539.2023.08.02.01.27.38; Wed, 02 Aug 2023 01:27:52 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=K8ktEoXk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233352AbjHBHi7 (ORCPT + 99 others); Wed, 2 Aug 2023 03:38:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40460 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232748AbjHBHh7 (ORCPT ); Wed, 2 Aug 2023 03:37:59 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D551935A5 for ; Wed, 2 Aug 2023 00:37:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1690961821; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type; bh=Af46NJKmEBmqy5H958slGnADxdkvZPSFCpD9BIDom1E=; b=K8ktEoXkDC0VHvlC8J18KFcIsNz1PRz4+xyG88/SDhQAvtCIr8ZI88Nkg4zOhuBtxMktyn Ai0c9JBXyUJgMY6NjeY3BAw6aFH2VCoHZeyixIB/X6Y8E4Ox/6w2tRs+i3wBlhw6kgk1oQ /tMf54ghoZvM1aqYEMYIcWwJIyjdT9A= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-298-pNGBElBeMeG9lip0cBHItQ-1; Wed, 02 Aug 2023 03:36:55 -0400 X-MC-Unique: pNGBElBeMeG9lip0cBHItQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C335E3828887; Wed, 2 Aug 2023 07:36:53 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.131]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1C433F7820; Wed, 2 Aug 2023 07:36:51 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 From: David Howells To: netdev@vger.kernel.org, Willem de Bruijn cc: dhowells@redhat.com, syzbot+f527b971b4bdc8e79f9e@syzkaller.appspotmail.com, bpf@vger.kernel.org, brauner@kernel.org, davem@davemloft.net, dsahern@kernel.org, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, axboe@kernel.dk, viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org, syzkaller-bugs@googlegroups.com, linux-kernel@vger.kernel.org Subject: [PATCH net-next] udp6: Fix __ip6_append_data()'s handling of MSG_SPLICE_PAGES MIME-Version: 1.0 Content-ID: <1580951.1690961810.1@warthog.procyon.org.uk> Date: Wed, 02 Aug 2023 08:36:50 +0100 Message-ID: <1580952.1690961810@warthog.procyon.org.uk> X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773105182179021854 X-GMAIL-MSGID: 1773105182179021854 __ip6_append_data() can has a similar problem to __ip_append_data()[1] when asked to splice into a partially-built UDP message that has more than the frag-limit data and up to the MTU limit, but in the ipv6 case, it errors out with EINVAL. This can be triggered with something like: pipe(pfd); sfd = socket(AF_INET6, SOCK_DGRAM, 0); connect(sfd, ...); send(sfd, buffer, 8137, MSG_CONFIRM|MSG_MORE); write(pfd[1], buffer, 8); splice(pfd[0], 0, sfd, 0, 0x4ffe0ul, 0); where the amount of data given to send() is dependent on the MTU size (in this instance an interface with an MTU of 8192). The problem is that the calculation of the amount to copy in __ip6_append_data() goes negative in two places, but a check has been put in to give an error in this case. This happens because when pagedlen > 0 (which happens for MSG_ZEROCOPY and MSG_SPLICE_PAGES), the terms in: copy = datalen - transhdrlen - fraggap - pagedlen; then mostly cancel when pagedlen is substituted for, leaving just -fraggap. Fix this by: (1) Insert a note about the dodgy calculation of 'copy'. (2) If MSG_SPLICE_PAGES, clear copy if it is negative from the above equation, so that 'offset' isn't regressed and 'length' isn't increased, which will mean that length and thus copy should match the amount left in the iterator. (3) When handling MSG_SPLICE_PAGES, give a warning and return -EIO if we're asked to splice more than is in the iterator. It might be better to not give the warning or even just give a 'short' write. (4) If MSG_SPLICE_PAGES, override the copy<0 check. [!] Note that this should also affect MSG_ZEROCOPY, but that will return -EINVAL for the range of send sizes that requires the skbuff to be split. Signed-off-by: David Howells cc: Willem de Bruijn cc: "David S. Miller" cc: Eric Dumazet cc: Jakub Kicinski cc: Paolo Abeni cc: David Ahern cc: Jens Axboe cc: Matthew Wilcox cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/000000000000881d0606004541d1@google.com/ [1] Reviewed-by: Willem de Bruijn --- net/ipv6/ip6_output.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 1e8c90e97608..bc96559bbf0f 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1693,7 +1693,10 @@ static int __ip6_append_data(struct sock *sk, fraglen = datalen + fragheaderlen; copy = datalen - transhdrlen - fraggap - pagedlen; - if (copy < 0) { + /* [!] NOTE: copy may be negative if pagedlen>0 + * because then the equation may reduces to -fraggap. + */ + if (copy < 0 && !(flags & MSG_SPLICE_PAGES)) { err = -EINVAL; goto error; } @@ -1744,6 +1747,8 @@ static int __ip6_append_data(struct sock *sk, err = -EFAULT; kfree_skb(skb); goto error; + } else if (flags & MSG_SPLICE_PAGES) { + copy = 0; } offset += copy; @@ -1791,6 +1796,10 @@ static int __ip6_append_data(struct sock *sk, } else if (flags & MSG_SPLICE_PAGES) { struct msghdr *msg = from; + err = -EIO; + if (WARN_ON_ONCE(copy > msg->msg_iter.count)) + goto error; + err = skb_splice_from_iter(skb, &msg->msg_iter, copy, sk->sk_allocation); if (err < 0)