From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EFC5BC433E8 for ; Mon, 27 Jul 2020 13:24:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D7F0F2070A for ; Mon, 27 Jul 2020 13:24:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726313AbgG0NY4 convert rfc822-to-8bit (ORCPT ); Mon, 27 Jul 2020 09:24:56 -0400 Received: from eu-smtp-delivery-151.mimecast.com ([185.58.86.151]:27872 "EHLO eu-smtp-delivery-151.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728788AbgG0NYw (ORCPT ); Mon, 27 Jul 2020 09:24:52 -0400 Received: from AcuMS.aculab.com (156.67.243.126 [156.67.243.126]) (Using TLS) by relay.mimecast.com with ESMTP id uk-mta-193-MlZusWDpPT2OM9ZpGGXrfQ-1; Mon, 27 Jul 2020 14:24:47 +0100 X-MC-Unique: MlZusWDpPT2OM9ZpGGXrfQ-1 Received: from AcuMS.Aculab.com (fd9f:af1c:a25b:0:43c:695e:880f:8750) by AcuMS.aculab.com (fd9f:af1c:a25b:0:43c:695e:880f:8750) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Mon, 27 Jul 2020 14:24:45 +0100 Received: from AcuMS.Aculab.com ([fe80::43c:695e:880f:8750]) by AcuMS.aculab.com ([fe80::43c:695e:880f:8750%12]) with mapi id 15.00.1347.000; Mon, 27 Jul 2020 14:24:45 +0100 From: David Laight To: 'Ido Schimmel' , Christoph Hellwig CC: "David S. Miller" , Jakub Kicinski , Alexei Starovoitov , Daniel Borkmann , Alexey Kuznetsov , Hideaki YOSHIFUJI , Eric Dumazet , "linux-crypto@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "netdev@vger.kernel.org" , "bpf@vger.kernel.org" , "netfilter-devel@vger.kernel.org" , "coreteam@netfilter.org" , "linux-sctp@vger.kernel.org" , "linux-hams@vger.kernel.org" , "linux-bluetooth@vger.kernel.org" , "bridge@lists.linux-foundation.org" , "linux-can@vger.kernel.org" , "dccp@vger.kernel.org" , "linux-decnet-user@lists.sourceforge.net" , "linux-wpan@vger.kernel.org" , "linux-s390@vger.kernel.org" , "mptcp@lists.01.org" , "lvs-devel@vger.kernel.org" , "rds-devel@oss.oracle.com" , "linux-afs@lists.infradead.org" , "tipc-discussion@lists.sourceforge.net" , "linux-x25@vger.kernel.org" Subject: RE: [PATCH 19/26] net/ipv6: switch ipv6_flowlabel_opt to sockptr_t Thread-Topic: [PATCH 19/26] net/ipv6: switch ipv6_flowlabel_opt to sockptr_t Thread-Index: AQHWZA+bicrTMJDvYkuXLSSepOLT0qkbaJEw Date: Mon, 27 Jul 2020 13:24:45 +0000 Message-ID: <8c747034a5b641d18734de5f4d3a7507@AcuMS.aculab.com> References: <20200723060908.50081-1-hch@lst.de> <20200723060908.50081-20-hch@lst.de> <20200727121505.GA1804864@shredder> In-Reply-To: <20200727121505.GA1804864@shredder> Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.202.205.107] MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: aculab.com Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8BIT Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org From: Ido Schimmel > Sent: 27 July 2020 13:15 > On Thu, Jul 23, 2020 at 08:09:01AM +0200, Christoph Hellwig wrote: > > Pass a sockptr_t to prepare for set_fs-less handling of the kernel > > pointer from bpf-cgroup. > > > > Note that the get case is pretty weird in that it actually copies data > > back to userspace from setsockopt. > > > > Signed-off-by: Christoph Hellwig > > --- > > include/net/ipv6.h | 2 +- > > net/ipv6/ip6_flowlabel.c | 16 +++++++++------- > > net/ipv6/ipv6_sockglue.c | 2 +- > > 3 files changed, 11 insertions(+), 9 deletions(-) > > > > diff --git a/include/net/ipv6.h b/include/net/ipv6.h > > index 262fc88dbd7e2f..4c9d89b5d73268 100644 > > --- a/include/net/ipv6.h > > +++ b/include/net/ipv6.h > > @@ -406,7 +406,7 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space, > > struct ip6_flowlabel *fl, > > struct ipv6_txoptions *fopt); > > void fl6_free_socklist(struct sock *sk); > > -int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen); > > +int ipv6_flowlabel_opt(struct sock *sk, sockptr_t optval, int optlen); > > int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq, > > int flags); > > int ip6_flowlabel_init(void); > > diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c > > index 27ee6de9beffc4..6b3c315f3d461a 100644 > > --- a/net/ipv6/ip6_flowlabel.c > > +++ b/net/ipv6/ip6_flowlabel.c > > @@ -371,7 +371,7 @@ static int fl6_renew(struct ip6_flowlabel *fl, unsigned long linger, unsigned lo > > > > static struct ip6_flowlabel * > > fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq, > > - char __user *optval, int optlen, int *err_p) > > + sockptr_t optval, int optlen, int *err_p) > > { > > struct ip6_flowlabel *fl = NULL; > > int olen; > > @@ -401,7 +401,8 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq, > > memset(fl->opt, 0, sizeof(*fl->opt)); > > fl->opt->tot_len = sizeof(*fl->opt) + olen; > > err = -EFAULT; > > - if (copy_from_user(fl->opt+1, optval+CMSG_ALIGN(sizeof(*freq)), olen)) > > + sockptr_advance(optval, CMSG_ALIGN(sizeof(*freq))); > > + if (copy_from_sockptr(fl->opt + 1, optval, olen)) > > goto done; > > > > msg.msg_controllen = olen; > > @@ -604,7 +605,7 @@ static int ipv6_flowlabel_renew(struct sock *sk, struct in6_flowlabel_req *freq) > > } > > > > static int ipv6_flowlabel_get(struct sock *sk, struct in6_flowlabel_req *freq, > > - void __user *optval, int optlen) > > + sockptr_t optval, int optlen) > > { > > struct ipv6_fl_socklist *sfl, *sfl1 = NULL; > > struct ip6_flowlabel *fl, *fl1 = NULL; > > @@ -702,8 +703,9 @@ static int ipv6_flowlabel_get(struct sock *sk, struct in6_flowlabel_req *freq, > > goto recheck; > > > > if (!freq->flr_label) { > > - if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label, > > - &fl->label, sizeof(fl->label))) { > > + sockptr_advance(optval, > > + offsetof(struct in6_flowlabel_req, flr_label)); > > Christoph, > > I see a regression with IPv6 flowlabel that I bisected to this patch. > When passing '-F 0' to 'ping' the flow label should be random, yet it's > the same every time after this patch. > > It seems that the pointer is never advanced after the call to > sockptr_advance() because it is passed by value and not by reference. > Even if you were to pass it by reference I think you would later need to > call sockptr_decrease() or something similar. Otherwise it is very > error-prone. Depending on the other checks you may also be able to cross from user addresses to kernel ones. At the minimum sockptr_advance() has to fail if the boundary would be crossed. > Maybe adding an offset to copy_to_sockptr() and copy_from_sockptr() is > better? The 'is this a kernel or user copy' needs to use the base address from the system call. So you do need the offset passed in to copy_to/from_sockptr(). Clearly churn can be reduced by using a #define or static inline for the common case. The alternative is to pass a 'fat pointer' through than can contain an offset as well as the user/kernel bases and expected length. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)