Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp4570270ybi; Sat, 6 Jul 2019 08:01:32 -0700 (PDT) X-Google-Smtp-Source: APXvYqzYkHw8CQ98wJU3WOB1u68DH4eeGlQKGfwPWEjcMVEhPM+VrYuZ1jeJ+D/FCylqRq7/dGB1 X-Received: by 2002:a63:18d:: with SMTP id 135mr11477479pgb.62.1562425292370; Sat, 06 Jul 2019 08:01:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562425292; cv=none; d=google.com; s=arc-20160816; b=YPAk9zoMBONGnfWCwJPNwJsmbxU0BGlcS++bsnqX/P3AV49hdd9+R3fGtAPLZg9Vcr wnlxVlRKQWVsrVkCviBvXOd2w6UAWjQ1DNI6c8HE35gYsjqCR7Bl4vkdwy09/paMLejx gKZhszHO1iHFHXd173UTj7IJEVX4PPRbg84mA1fScaXYWWRTrS26VpSm7MdQ3rA+Nv56 VUqNYIyur7GEg1SYvlysSuw6Rpx+o7PPKMZna3sOqwv7V68LmSgKwHyTiNi+ggrdg4IO IwjaWbcrruSjGXSVUlvGcQhI4d6shQLDZvRqggDoszeXs57+ldgAR+oPg7IEauZfUv/9 G84A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=ABRYazN7fMRoMxcDOaIkvNNT/7jZ5M9IEIEl1UlgrFc=; b=VgCM0kX3MhTouivejqw38L7cg0y4B9BY+6U3qaAh4AQhBbIkx7qkeVvtKPtMWsBsMF ht8D04+x3T1iq4gJkNO+r6ByYEfLV8dNcofEiIel5aWjeSnCTQmVhhj00kTNGtz93Gcl SX3dCo1I9UiaVo5R5o0wzJpj5SRgUFFwUFsfHIP8pdviXYBr5ne2g87i8vGlpmqZLmRM r4srLbOMhfcHa7kyuTIWXclXoWCg034nVMLxQu/lnQXD8uMhO2MtoY9K+ejRhAtaPpXB yUXJmwahxqou5Q+LASwiM6Uw1xz1lZ3J8bKYZz//HQ7fn9R44UsMJjQEp5kdIZ2T1lp8 q4Tg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j8si10857093plt.303.2019.07.06.08.01.17; Sat, 06 Jul 2019 08:01:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727189AbfGFO7g (ORCPT + 99 others); Sat, 6 Jul 2019 10:59:36 -0400 Received: from mx2.mailbox.org ([80.241.60.215]:34540 "EHLO mx2.mailbox.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726702AbfGFO7f (ORCPT ); Sat, 6 Jul 2019 10:59:35 -0400 Received: from smtp1.mailbox.org (smtp1.mailbox.org [80.241.60.240]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mx2.mailbox.org (Postfix) with ESMTPS id 1C229A01B0; Sat, 6 Jul 2019 16:59:30 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter02.heinlein-hosting.de (spamfilter02.heinlein-hosting.de [80.241.56.116]) (amavisd-new, port 10030) with ESMTP id UYQQdEKKt3Aq; Sat, 6 Jul 2019 16:59:21 +0200 (CEST) From: Aleksa Sarai To: Al Viro , Jeff Layton , "J. Bruce Fields" , Arnd Bergmann , David Howells , Shuah Khan , Shuah Khan Cc: Aleksa Sarai , Eric Biederman , Andy Lutomirski , Andrew Morton , Alexei Starovoitov , Kees Cook , Jann Horn , Christian Brauner , Tycho Andersen , David Drysdale , Chanho Min , Oleg Nesterov , Aleksa Sarai , Linus Torvalds , containers@lists.linux-foundation.org, linux-alpha@vger.kernel.org, linux-api@vger.kernel.org, linux-arch@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-fsdevel@vger.kernel.org, linux-ia64@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-m68k@lists.linux-m68k.org, linux-mips@vger.kernel.org, linux-parisc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, linux-sh@vger.kernel.org, linux-xtensa@linux-xtensa.org, sparclinux@vger.kernel.org Subject: [PATCH v9 04/10] namei: split out nd->dfd handling to dirfd_path_init Date: Sun, 7 Jul 2019 00:57:31 +1000 Message-Id: <20190706145737.5299-5-cyphar@cyphar.com> In-Reply-To: <20190706145737.5299-1-cyphar@cyphar.com> References: <20190706145737.5299-1-cyphar@cyphar.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Previously, path_init's handling of *at(dfd, ...) was only done once, but with LOOKUP_BENEATH (and LOOKUP_IN_ROOT) we have to parse the initial nd->path at different times (before or after absolute path handling) depending on whether we have been asked to scope resolution within a root. Signed-off-by: Aleksa Sarai --- fs/namei.c | 103 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 44 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 4895717d2760..b490bcf855f8 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2257,9 +2257,59 @@ static int link_path_walk(const char *name, struct nameidata *nd) } } +/* + * Configure nd->path based on the nd->dfd. This is only used as part of + * path_init(). + */ +static inline int dirfd_path_init(struct nameidata *nd) +{ + if (nd->dfd == AT_FDCWD) { + if (nd->flags & LOOKUP_RCU) { + struct fs_struct *fs = current->fs; + unsigned seq; + + do { + seq = read_seqcount_begin(&fs->seq); + nd->path = fs->pwd; + nd->inode = nd->path.dentry->d_inode; + nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); + } while (read_seqcount_retry(&fs->seq, seq)); + } else { + get_fs_pwd(current->fs, &nd->path); + nd->inode = nd->path.dentry->d_inode; + } + } else { + /* Caller must check execute permissions on the starting path component */ + struct fd f = fdget_raw(nd->dfd); + struct dentry *dentry; + + if (!f.file) + return -EBADF; + + dentry = f.file->f_path.dentry; + + if (*nd->name->name && unlikely(!d_can_lookup(dentry))) { + fdput(f); + return -ENOTDIR; + } + + nd->path = f.file->f_path; + if (nd->flags & LOOKUP_RCU) { + nd->inode = nd->path.dentry->d_inode; + nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); + } else { + path_get(&nd->path); + nd->inode = nd->path.dentry->d_inode; + } + fdput(f); + } + return 0; +} + /* must be paired with terminate_walk() */ static const char *path_init(struct nameidata *nd, unsigned flags) { + int error; const char *s = nd->name->name; if (!*s) @@ -2293,52 +2343,17 @@ static const char *path_init(struct nameidata *nd, unsigned flags) nd->m_seq = read_seqbegin(&mount_lock); if (*s == '/') { - set_root(nd); - if (likely(!nd_jump_root(nd))) - return s; - return ERR_PTR(-ECHILD); - } else if (nd->dfd == AT_FDCWD) { - if (flags & LOOKUP_RCU) { - struct fs_struct *fs = current->fs; - unsigned seq; - - do { - seq = read_seqcount_begin(&fs->seq); - nd->path = fs->pwd; - nd->inode = nd->path.dentry->d_inode; - nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); - } while (read_seqcount_retry(&fs->seq, seq)); - } else { - get_fs_pwd(current->fs, &nd->path); - nd->inode = nd->path.dentry->d_inode; - } - return s; - } else { - /* Caller must check execute permissions on the starting path component */ - struct fd f = fdget_raw(nd->dfd); - struct dentry *dentry; - - if (!f.file) - return ERR_PTR(-EBADF); - - dentry = f.file->f_path.dentry; - - if (*s && unlikely(!d_can_lookup(dentry))) { - fdput(f); - return ERR_PTR(-ENOTDIR); - } - - nd->path = f.file->f_path; - if (flags & LOOKUP_RCU) { - nd->inode = nd->path.dentry->d_inode; - nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); - } else { - path_get(&nd->path); - nd->inode = nd->path.dentry->d_inode; - } - fdput(f); + if (likely(!nd->root.mnt)) + set_root(nd); + error = nd_jump_root(nd); + if (unlikely(error)) + s = ERR_PTR(error); return s; } + error = dirfd_path_init(nd); + if (unlikely(error)) + return ERR_PTR(error); + return s; } static const char *trailing_symlink(struct nameidata *nd) -- 2.22.0