Received: by 2002:ac0:de83:0:0:0:0:0 with SMTP id b3csp1375495imk; Mon, 4 Jul 2022 01:37:07 -0700 (PDT) X-Google-Smtp-Source: AGRyM1umDVEdtuV0Z4tAk85Wq85U3phZLQ+zrET0uY84X2IAqThG1qQOhiI2+cINlUFq6EvMW4Ro X-Received: by 2002:a17:907:3e81:b0:726:9615:d14d with SMTP id hs1-20020a1709073e8100b007269615d14dmr27332269ejc.517.1656923827000; Mon, 04 Jul 2022 01:37:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656923826; cv=none; d=google.com; s=arc-20160816; b=GDHntts8AwTFiV7N5jtISWvt6II8K+xaD6+BdQCSCH6qd6FNk4AUTnd2VkmYxNYhTE OvHe5PFs6lpJyJEUeZeDOKTI0zfM80SUMDgSCTXqBoiAmDxHETFFHgosJzw6GnuitKxA PsbnECGphTRfcxBaIH9PckI5vGVjm/tVWkV78JsdveZEf+0hTeyeybgkfmjgSMzkFWcY USsLit7FjgjmrXbeS8CZf3bG/Z21yd/1WauZwoyTZlGQ5dbrvHd541hGR+P7Ae4laHsI bVt3hBGw5yTjRgzNOPEyYyctJxxt/4msyU5M3tvWMsv15NW21GI/HoqL1KHHa/1Wcchv 6NLg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=oAjJ2G+6gAo3NoQXMKWlZ5LJd5LqVOnZ6pcF/XS/a/o=; b=mzCGiRy84e/KxuB0T//CLvl7WjnbJi2xA8omJ0hIFFdkhfDP2JL4v5PgPR/a0zgNI6 3SFfRRhETWdqrlsw/AqmIiBYOOckYj7tYGUQ89blKLVysTiD4cq3di3IQQ/bi9K7frUb 0kHEJyPD9DFbOFPu2NNk5xXJlP54Tj0r4MW/cYuX4VvRM4Jz3a5bp4Wiy3F7uQztINoz vSCVL9YtbIvpzd6mQrRFL8SQNYeqxwOblSAZE9lBTSbWLAJTBxnqfpjdKd0Csy3zOyge 9uG+mO/BId0Z/J1AhIZRArIs0QtS48qzfiKfrHsuGoDkmRVId/CNJ4gg+0U87k6sjH8u H6YQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=UXFZDwr6; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p7-20020a170906498700b0072677faec75si15320289eju.872.2022.07.04.01.36.42; Mon, 04 Jul 2022 01:37:06 -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=@google.com header.s=20210112 header.b=UXFZDwr6; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232172AbiGDIVi (ORCPT + 99 others); Mon, 4 Jul 2022 04:21:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232491AbiGDIVg (ORCPT ); Mon, 4 Jul 2022 04:21:36 -0400 Received: from mail-yb1-xb30.google.com (mail-yb1-xb30.google.com [IPv6:2607:f8b0:4864:20::b30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D632388D for ; Mon, 4 Jul 2022 01:21:30 -0700 (PDT) Received: by mail-yb1-xb30.google.com with SMTP id o2so10311805yba.7 for ; Mon, 04 Jul 2022 01:21:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=oAjJ2G+6gAo3NoQXMKWlZ5LJd5LqVOnZ6pcF/XS/a/o=; b=UXFZDwr6JBwK2q5qPr/COIO9qmmIz9lmrhGw7w7/rzs+kfcHPRyBR1RIINfbYG+wC0 ne/flXlPkTHYqFJr7xwP+baPm2vcQghjbKQnWmhHZ0Seq8/3bLO3ZtCmE7HyrCD+uXa3 Ak/IwYZXkTUEMvR4YSvk8ba/Jnedo7sX5W1vwhQmtQ79ea87ru41pUWXS1vpPyIeQqYK Zg2+q9IDq2h7C9C0zij4dwI3F48k4KixG8AlVMNy8TDrMHhmvlbeUxvGZfoOL38s+OB7 AXxHgZI9c53kiB46OCcN3Ptf8FT4Ep7SubW8z9dPvEV0ixRTzOi1JVf6hWlMGt1IvaNV fE5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=oAjJ2G+6gAo3NoQXMKWlZ5LJd5LqVOnZ6pcF/XS/a/o=; b=kmiLL8dubLTXur7cmeUenls4yaMDs80kMXGDrxqXIlgGOFS6fBFG2e1rS1fry9eqW8 rypP/3d8LojQVUSciVkAYRNUES+STUvcu/hU/e6Jbnxz6ECany8J1g6ZueEpqQiK8rsH MYh1DMeHJka3HahoJU5dwmrf7wRReTz2A6ENT+EQhWVzR73KcZQYvRUu9IQ6YKgrLWmU wbUv9msDhbjX3c7IBFf+/OsqID7FxkHq883SLY1xU39uErbP9pZ4qiX8CxwYcJpAA2Xc iET5h0FmqhepsA8OmHHjQQ2gYvKsEsUotnpVGnGlJtLZzf2pmiCN5R0q2O8R/iPAg5sE K0ig== X-Gm-Message-State: AJIora8UhLsJXwIJzrJIo28OEhsbQaq6PSWkpKk9JTYc74BrK/9txTYW HueueFyCQs8HnqhjLdNgeNV2soIIYdVHFCcQqiomIA== X-Received: by 2002:a25:6b0b:0:b0:66e:445a:17bb with SMTP id g11-20020a256b0b000000b0066e445a17bbmr5396058ybc.147.1656922889083; Mon, 04 Jul 2022 01:21:29 -0700 (PDT) MIME-Version: 1.0 References: <20220701142310.2188015-1-glider@google.com> <20220701142310.2188015-44-glider@google.com> In-Reply-To: From: Alexander Potapenko Date: Mon, 4 Jul 2022 10:20:53 +0200 Message-ID: Subject: Re: [PATCH v4 43/45] namei: initialize parameters passed to step_into() To: Al Viro Cc: Linus Torvalds , Alexei Starovoitov , Andrew Morton , Andrey Konovalov , Andy Lutomirski , Arnd Bergmann , Borislav Petkov , Christoph Hellwig , Christoph Lameter , David Rientjes , Dmitry Vyukov , Eric Dumazet , Greg Kroah-Hartman , Herbert Xu , Ilya Leoshkevich , Ingo Molnar , Jens Axboe , Joonsoo Kim , Kees Cook , Marco Elver , Mark Rutland , Matthew Wilcox , "Michael S. Tsirkin" , Pekka Enberg , Peter Zijlstra , Petr Mladek , Steven Rostedt , Thomas Gleixner , Vasily Gorbik , Vegard Nossum , Vlastimil Babka , kasan-dev , Linux-MM , linux-arch , Linux Kernel Mailing List , Evgenii Stepanov , Nathan Chancellor , Nick Desaulniers , Segher Boessenkool , Vitaly Buka , linux-toolchains Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-17.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL,USER_IN_DEF_SPF_WL 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 On Mon, Jul 4, 2022 at 4:53 AM Al Viro wrote: > > On Sat, Jul 02, 2022 at 10:23:16AM -0700, Linus Torvalds wrote: > > > Al - can you please take a quick look? > > FWIW, trying to write a coherent documentation had its usual effect... > The thing is, we don't really need to fetch the inode that early. > All we really care about is that in RCU mode ->d_seq gets sampled > before we fetch ->d_inode *and* we don't treat "it looks negative" > as hard -ENOENT in case of ->d_seq mismatch. > > Which can be bloody well left to step_into(). So we don't need > to pass it inode argument at all - just dentry and seq. Makes > a bunch of functions simpler as well... > > It does *not* deal with the "uninitialized" seq argument in > !RCU case; I'll handle that in the followup, but that's a separate > story, IMO (and very clearly a false positive). I can confirm that your patch fixes KMSAN reports on inode, yet the following reports still persist: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D BUG: KMSAN: uninit-value in walk_component+0x5e7/0x6c0 fs/namei.c:1996 walk_component+0x5e7/0x6c0 fs/namei.c:1996 lookup_last fs/namei.c:2445 path_lookupat+0x27d/0x6f0 fs/namei.c:2468 filename_lookup+0x24c/0x800 fs/namei.c:2497 kern_path+0x79/0x3a0 fs/namei.c:2587 init_stat+0x72/0x13f fs/init.c:132 clean_path+0x74/0x24c init/initramfs.c:339 do_name+0x12d/0xc17 init/initramfs.c:371 write_buffer init/initramfs.c:457 unpack_to_rootfs+0x49a/0xd9e init/initramfs.c:510 do_populate_rootfs+0x57/0x40f init/initramfs.c:699 async_run_entry_fn+0x8f/0x400 kernel/async.c:127 process_one_work+0xb27/0x13e0 kernel/workqueue.c:2289 worker_thread+0x1076/0x1d60 kernel/workqueue.c:2436 kthread+0x31b/0x430 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 ??:? Local variable seq created at: walk_component+0x46/0x6c0 fs/namei.c:1981 lookup_last fs/namei.c:2445 path_lookupat+0x27d/0x6f0 fs/namei.c:2468 CPU: 0 PID: 10 Comm: kworker/u9:0 Tainted: G B 5.19.0-rc4-00059-gcf2d25715943-dirty #103 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/= 2014 Workqueue: events_unbound async_run_entry_fn =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D What makes you think they are false positives? Is the scenario I described above: """ In particular, if the call to lookup_fast() in walk_component() returns NULL, and lookup_slow() returns a valid dentry, then the `seq` and `inode` will remain uninitialized until the call to step_into() """ impossible? > Cumulative diff follows; splitup is in #work.namei. Comments? > > diff --git a/fs/namei.c b/fs/namei.c > index 1f28d3f463c3..7f4f61ade9e3 100644 > --- a/fs/namei.c > +++ b/fs/namei.c > @@ -1467,7 +1467,7 @@ EXPORT_SYMBOL(follow_down); > * we meet a managed dentry that would need blocking. > */ > static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, > - struct inode **inode, unsigned *seqp) > + unsigned *seqp) > { > struct dentry *dentry =3D path->dentry; > unsigned int flags =3D dentry->d_flags; > @@ -1497,13 +1497,6 @@ static bool __follow_mount_rcu(struct nameidata *n= d, struct path *path, > dentry =3D path->dentry =3D mounted->mnt.= mnt_root; > nd->state |=3D ND_JUMPED; > *seqp =3D read_seqcount_begin(&dentry->d_= seq); > - *inode =3D dentry->d_inode; > - /* > - * We don't need to re-check ->d_seq afte= r this > - * ->d_inode read - there will be an RCU = delay > - * between mount hash removal and ->mnt_r= oot > - * becoming unpinned. > - */ > flags =3D dentry->d_flags; > continue; > } > @@ -1515,8 +1508,7 @@ static bool __follow_mount_rcu(struct nameidata *nd= , struct path *path, > } > > static inline int handle_mounts(struct nameidata *nd, struct dentry *den= try, > - struct path *path, struct inode **inode, > - unsigned int *seqp) > + struct path *path, unsigned int *seqp) > { > bool jumped; > int ret; > @@ -1525,9 +1517,7 @@ static inline int handle_mounts(struct nameidata *n= d, struct dentry *dentry, > path->dentry =3D dentry; > if (nd->flags & LOOKUP_RCU) { > unsigned int seq =3D *seqp; > - if (unlikely(!*inode)) > - return -ENOENT; > - if (likely(__follow_mount_rcu(nd, path, inode, seqp))) > + if (likely(__follow_mount_rcu(nd, path, seqp))) > return 0; > if (!try_to_unlazy_next(nd, dentry, seq)) > return -ECHILD; > @@ -1547,7 +1537,6 @@ static inline int handle_mounts(struct nameidata *n= d, struct dentry *dentry, > if (path->mnt !=3D nd->path.mnt) > mntput(path->mnt); > } else { > - *inode =3D d_backing_inode(path->dentry); > *seqp =3D 0; /* out of RCU mode, so the value doesn't mat= ter */ > } > return ret; > @@ -1607,9 +1596,7 @@ static struct dentry *__lookup_hash(const struct qs= tr *name, > return dentry; > } > > -static struct dentry *lookup_fast(struct nameidata *nd, > - struct inode **inode, > - unsigned *seqp) > +static struct dentry *lookup_fast(struct nameidata *nd, unsigned *seqp) > { > struct dentry *dentry, *parent =3D nd->path.dentry; > int status =3D 1; > @@ -1628,22 +1615,11 @@ static struct dentry *lookup_fast(struct nameidat= a *nd, > return NULL; > } > > - /* > - * This sequence count validates that the inode matches > - * the dentry name information from lookup. > - */ > - *inode =3D d_backing_inode(dentry); > - if (unlikely(read_seqcount_retry(&dentry->d_seq, seq))) > - return ERR_PTR(-ECHILD); > - > - /* > + /* > * This sequence count validates that the parent had no > * changes while we did the lookup of the dentry above. > - * > - * The memory barrier in read_seqcount_begin of child is > - * enough, we can use __read_seqcount_retry here. > */ > - if (unlikely(__read_seqcount_retry(&parent->d_seq, nd->se= q))) > + if (unlikely(read_seqcount_retry(&parent->d_seq, nd->seq)= )) > return ERR_PTR(-ECHILD); > > *seqp =3D seq; > @@ -1838,13 +1814,21 @@ static const char *pick_link(struct nameidata *nd= , struct path *link, > * for the common case. > */ > static const char *step_into(struct nameidata *nd, int flags, > - struct dentry *dentry, struct inode *inode, unsigned= seq) > + struct dentry *dentry, unsigned seq) > { > struct path path; > - int err =3D handle_mounts(nd, dentry, &path, &inode, &seq); > + struct inode *inode; > + int err =3D handle_mounts(nd, dentry, &path, &seq); > > if (err < 0) > return ERR_PTR(err); > + inode =3D path.dentry->d_inode; > + if (unlikely(!inode)) { > + if ((nd->flags & LOOKUP_RCU) && > + read_seqcount_retry(&path.dentry->d_seq, seq)) > + return ERR_PTR(-ECHILD); > + return ERR_PTR(-ENOENT); > + } > if (likely(!d_is_symlink(path.dentry)) || > ((flags & WALK_TRAILING) && !(nd->flags & LOOKUP_FOLLOW)) || > (flags & WALK_NOFOLLOW)) { > @@ -1870,9 +1854,7 @@ static const char *step_into(struct nameidata *nd, = int flags, > return pick_link(nd, &path, inode, seq, flags); > } > > -static struct dentry *follow_dotdot_rcu(struct nameidata *nd, > - struct inode **inodep, > - unsigned *seqp) > +static struct dentry *follow_dotdot_rcu(struct nameidata *nd, unsigned *= seqp) > { > struct dentry *parent, *old; > > @@ -1895,7 +1877,6 @@ static struct dentry *follow_dotdot_rcu(struct name= idata *nd, > } > old =3D nd->path.dentry; > parent =3D old->d_parent; > - *inodep =3D parent->d_inode; > *seqp =3D read_seqcount_begin(&parent->d_seq); > if (unlikely(read_seqcount_retry(&old->d_seq, nd->seq))) > return ERR_PTR(-ECHILD); > @@ -1910,9 +1891,7 @@ static struct dentry *follow_dotdot_rcu(struct name= idata *nd, > return NULL; > } > > -static struct dentry *follow_dotdot(struct nameidata *nd, > - struct inode **inodep, > - unsigned *seqp) > +static struct dentry *follow_dotdot(struct nameidata *nd, unsigned *seqp= ) > { > struct dentry *parent; > > @@ -1937,7 +1916,6 @@ static struct dentry *follow_dotdot(struct nameidat= a *nd, > return ERR_PTR(-ENOENT); > } > *seqp =3D 0; > - *inodep =3D parent->d_inode; > return parent; > > in_root: > @@ -1952,7 +1930,6 @@ static const char *handle_dots(struct nameidata *nd= , int type) > if (type =3D=3D LAST_DOTDOT) { > const char *error =3D NULL; > struct dentry *parent; > - struct inode *inode; > unsigned seq; > > if (!nd->root.mnt) { > @@ -1961,17 +1938,17 @@ static const char *handle_dots(struct nameidata *= nd, int type) > return error; > } > if (nd->flags & LOOKUP_RCU) > - parent =3D follow_dotdot_rcu(nd, &inode, &seq); > + parent =3D follow_dotdot_rcu(nd, &seq); > else > - parent =3D follow_dotdot(nd, &inode, &seq); > + parent =3D follow_dotdot(nd, &seq); > if (IS_ERR(parent)) > return ERR_CAST(parent); > if (unlikely(!parent)) > error =3D step_into(nd, WALK_NOFOLLOW, > - nd->path.dentry, nd->inode, nd->= seq); > + nd->path.dentry, nd->seq); > else > error =3D step_into(nd, WALK_NOFOLLOW, > - parent, inode, seq); > + parent, seq); > if (unlikely(error)) > return error; > > @@ -1995,7 +1972,6 @@ static const char *handle_dots(struct nameidata *nd= , int type) > static const char *walk_component(struct nameidata *nd, int flags) > { > struct dentry *dentry; > - struct inode *inode; > unsigned seq; > /* > * "." and ".." are special - ".." especially so because it has > @@ -2007,7 +1983,7 @@ static const char *walk_component(struct nameidata = *nd, int flags) > put_link(nd); > return handle_dots(nd, nd->last_type); > } > - dentry =3D lookup_fast(nd, &inode, &seq); > + dentry =3D lookup_fast(nd, &seq); > if (IS_ERR(dentry)) > return ERR_CAST(dentry); > if (unlikely(!dentry)) { > @@ -2017,7 +1993,7 @@ static const char *walk_component(struct nameidata = *nd, int flags) > } > if (!(flags & WALK_MORE) && nd->depth) > put_link(nd); > - return step_into(nd, flags, dentry, inode, seq); > + return step_into(nd, flags, dentry, seq); > } > > /* > @@ -2473,8 +2449,7 @@ static int handle_lookup_down(struct nameidata *nd) > { > if (!(nd->flags & LOOKUP_RCU)) > dget(nd->path.dentry); > - return PTR_ERR(step_into(nd, WALK_NOFOLLOW, > - nd->path.dentry, nd->inode, nd->seq)); > + return PTR_ERR(step_into(nd, WALK_NOFOLLOW, nd->path.dentry, nd->= seq)); > } > > /* Returns 0 and nd will be valid on success; Retuns error, otherwise. *= / > @@ -3394,7 +3369,6 @@ static const char *open_last_lookups(struct nameida= ta *nd, > int open_flag =3D op->open_flag; > bool got_write =3D false; > unsigned seq; > - struct inode *inode; > struct dentry *dentry; > const char *res; > > @@ -3410,7 +3384,7 @@ static const char *open_last_lookups(struct nameida= ta *nd, > if (nd->last.name[nd->last.len]) > nd->flags |=3D LOOKUP_FOLLOW | LOOKUP_DIRECTORY; > /* we _can_ be in RCU mode here */ > - dentry =3D lookup_fast(nd, &inode, &seq); > + dentry =3D lookup_fast(nd, &seq); > if (IS_ERR(dentry)) > return ERR_CAST(dentry); > if (likely(dentry)) > @@ -3464,7 +3438,7 @@ static const char *open_last_lookups(struct nameida= ta *nd, > finish_lookup: > if (nd->depth) > put_link(nd); > - res =3D step_into(nd, WALK_TRAILING, dentry, inode, seq); > + res =3D step_into(nd, WALK_TRAILING, dentry, seq); > if (unlikely(res)) > nd->flags &=3D ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL); > return res; --=20 Alexander Potapenko Software Engineer Google Germany GmbH Erika-Mann-Stra=C3=9Fe, 33 80636 M=C3=BCnchen Gesch=C3=A4ftsf=C3=BChrer: Paul Manicle, Liana Sebastian Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Diese E-Mail ist vertraulich. Falls Sie diese f=C3=A4lschlicherweise erhalten haben sollten, leiten Sie diese bitte nicht an jemand anderes weiter, l=C3=B6schen Sie alle Kopien und Anh=C3=A4nge davon und lassen Sie = mich bitte wissen, dass die E-Mail an die falsche Person gesendet wurde. This e-mail is confidential. If you received this communication by mistake, please don't forward it to anyone else, please erase all copies and attachments, and please let me know that it has gone to the wrong person.