Received: by 2002:a05:7412:e794:b0:fa:551:50a7 with SMTP id o20csp1537609rdd; Thu, 11 Jan 2024 02:05:30 -0800 (PST) X-Google-Smtp-Source: AGHT+IElQ5kqOmiFeWbLwaRwxbplxNH9wY9WldBAqRtSIIgT3K0aOJyx97eGOU1FJ+NVilWmbqU4 X-Received: by 2002:a05:690c:4588:b0:5d8:2b37:e085 with SMTP id gu8-20020a05690c458800b005d82b37e085mr337873ywb.20.1704967530028; Thu, 11 Jan 2024 02:05:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704967530; cv=none; d=google.com; s=arc-20160816; b=l31sk9fdcvmXQNbiWiXOPAXT3pOMT87AauORWEWpN9IcvwKEJyyauYvWypxC5Fi4oV iaFIlLlJDxdmQpkjG9LJeCCJkeq8PN1ApPqOMe9YDrEk8lKEPc6JIVyaq8AGbEYHII5B VIqKXd188WqdqAUoeBxH7S8cC43/Euo9zO8LmfhpYc/xJsDoptFLdg2ABgEZZm2WBAu+ BqWK8nkH1o6nfblB3yB8lqNckS2iK6J07KhnhCGlHsOqEAADG06CQjPXwWLVyyw2PRZh pow6VuyeW0WEtQlSAQhbti7HNKLy8cmPYwce+UxgYpRJ0LXhKmFa4GDyk3jFyqrCB+Cx 1lMA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:in-reply-to:content-disposition:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:references :message-id:subject:cc:to:from:date:dkim-signature; bh=AE+YN7mp8tF8D2TsFEMmNTNNM/8+22BnneF03zOJeSI=; fh=dr0lwBYSFTge2hAQEK2QACpoijsDFj8eMr7Rd91lUiU=; b=HWa5m7sQrq9q/1L61CnKLfVIp+EVFYzZM/2Bi7ZLaPoTKd7GQVXZtC6ubEyOudZg0a a1FkPZcw6HgaVWRcGpczfHxuaMlRK+z/1oO27gvufoaRe4KlS9uZrJaQOBOPHN9CXPZe cjCMWniELcRwdjwKT4L5qjYMJHbEd+D6/sylT1oDFjocUvzbreWfX1+REc1EfrvZnpWf qqKF6sH0+9jsqMXlWGOOPenTKGoVB+H/nJWYTEca6V/zUINxHgkKpzWJ+CwtSvu4o0Zk 4lpWkbPZTBHQQHdY9QBKJ7syd+OwLFgIQ8B4QM2HCuraQgghYyYZcaMdY/NaaxpiUZP/ wHtA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.org.uk header.s=zeniv-20220401 header.b=MxWgyTEi; spf=pass (google.com: domain of linux-kernel+bounces-23357-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-23357-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zeniv.linux.org.uk Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id r5-20020a05620a298500b0078320d0818csi604753qkp.254.2024.01.11.02.05.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jan 2024 02:05:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-23357-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.org.uk header.s=zeniv-20220401 header.b=MxWgyTEi; spf=pass (google.com: domain of linux-kernel+bounces-23357-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-23357-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zeniv.linux.org.uk Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id C49E21C2249D for ; Thu, 11 Jan 2024 10:05:29 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 97AF61401B; Thu, 11 Jan 2024 10:05:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="MxWgyTEi" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3ADB412E4B for ; Thu, 11 Jan 2024 10:05:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=AE+YN7mp8tF8D2TsFEMmNTNNM/8+22BnneF03zOJeSI=; b=MxWgyTEibe0nbD8DrPgp9yAtAH bVKTEPq1tCLdQWKI1WRnOtkqgM166AITsqWs8tg4V+sL1RIhwLy7C9pQbV5HovfqIs8N0WU5NvWXD Tu587/Y9atBTG3mQfotN6D9febysciM59ZBzJOelJxcICJ++lK301szSUoUYPMAMKAUyfqNJG6x0x y5X9TO+2AhKokrBlI+xOUSVmgOMeTB054YHtAenrBzxgf8ywjU2r+oa57IkL+WWpGekdjw2SEy6Q+ babGHgPGHq/VxO9S1EGRuFsM/fE2ALEWthfg2zR+ICBgNiHB7BUKotNjunxGoolFwAvALS+CQVkc0 fyaAcTag==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rNrvp-00C8wo-06; Thu, 11 Jan 2024 10:05:01 +0000 Date: Thu, 11 Jan 2024 10:05:01 +0000 From: Al Viro To: Linus Torvalds Cc: Josh Triplett , Kees Cook , Kees Cook , linux-kernel@vger.kernel.org, Alexey Dobriyan Subject: Re: [GIT PULL] execve updates for v6.8-rc1 Message-ID: <20240111100501.GU1674809@ZenIV> References: <202401081028.0E908F9E0A@keescook> <20240111094711.GT1674809@ZenIV> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20240111094711.GT1674809@ZenIV> Sender: Al Viro On Thu, Jan 11, 2024 at 09:47:11AM +0000, Al Viro wrote: > Doable, but really not pretty, especially since we'd need to massage > the caller as well... Less painful variant is > if (error == -ECHILD && (flags & LOOKUP_RCU)) > return ERR_PTR(-ECHILD); // keep file for non-rcu pass > *fp = NULL; > fput(file); > ... > on the way out; that won't help with -ESTALE side of things, but if we > hit *that*, struct file allocation overhead is really noise. Something like (completely untested) delta below, perhaps? diff --git a/fs/namei.c b/fs/namei.c index 5c318d657503..de770be9bb16 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3765,15 +3765,17 @@ static int do_o_path(struct nameidata *nd, unsigned flags, struct file *file) return error; } -static struct file *path_openat(struct nameidata *nd, +static int path_openat(struct nameidata *nd, struct file **fp, const struct open_flags *op, unsigned flags) { - struct file *file; + struct file *file = *fp; int error; - file = alloc_empty_file(op->open_flag, current_cred()); - if (IS_ERR(file)) - return file; + if (!file) { + file = alloc_empty_file(op->open_flag, current_cred()); + if (IS_ERR(file)) + return PTR_ERR(file); + } if (unlikely(file->f_flags & __O_TMPFILE)) { error = do_tmpfile(nd, flags, op, file); @@ -3789,11 +3791,17 @@ static struct file *path_openat(struct nameidata *nd, terminate_walk(nd); } if (likely(!error)) { - if (likely(file->f_mode & FMODE_OPENED)) - return file; + if (likely(file->f_mode & FMODE_OPENED)) { + *fp = file; + return 0; + } WARN_ON(1); error = -EINVAL; } + if (error == -ECHILD && (flags & LOOKUP_RCU)) { + *fp = file; // reuse on the next pass + return -ECHILD; + } fput(file); if (error == -EOPENSTALE) { if (flags & LOOKUP_RCU) @@ -3801,7 +3809,7 @@ static struct file *path_openat(struct nameidata *nd, else error = -ESTALE; } - return ERR_PTR(error); + return error; } struct file *do_filp_open(int dfd, struct filename *pathname, @@ -3809,25 +3817,27 @@ struct file *do_filp_open(int dfd, struct filename *pathname, { struct nameidata nd; int flags = op->lookup_flags; - struct file *filp; + struct file *file = NULL; + int err; set_nameidata(&nd, dfd, pathname, NULL); - filp = path_openat(&nd, op, flags | LOOKUP_RCU); - if (unlikely(filp == ERR_PTR(-ECHILD))) - filp = path_openat(&nd, op, flags); - if (unlikely(filp == ERR_PTR(-ESTALE))) - filp = path_openat(&nd, op, flags | LOOKUP_REVAL); + err = path_openat(&nd, &file, op, flags | LOOKUP_RCU); + if (unlikely(err == -ECHILD)) + err = path_openat(&nd, &file, op, flags); + if (unlikely(err == -ESTALE)) + err = path_openat(&nd, &file, op, flags | LOOKUP_REVAL); restore_nameidata(); - return filp; + return unlikely(err) ? ERR_PTR(err) : file; } struct file *do_file_open_root(const struct path *root, const char *name, const struct open_flags *op) { struct nameidata nd; - struct file *file; + struct file *file = NULL; struct filename *filename; int flags = op->lookup_flags; + int err; if (d_is_symlink(root->dentry) && op->intent & LOOKUP_OPEN) return ERR_PTR(-ELOOP); @@ -3837,14 +3847,14 @@ struct file *do_file_open_root(const struct path *root, return ERR_CAST(filename); set_nameidata(&nd, -1, filename, root); - file = path_openat(&nd, op, flags | LOOKUP_RCU); - if (unlikely(file == ERR_PTR(-ECHILD))) - file = path_openat(&nd, op, flags); - if (unlikely(file == ERR_PTR(-ESTALE))) - file = path_openat(&nd, op, flags | LOOKUP_REVAL); + err = path_openat(&nd, &file, op, flags | LOOKUP_RCU); + if (unlikely(err == -ECHILD)) + err = path_openat(&nd, &file, op, flags); + if (unlikely(err == -ESTALE)) + err = path_openat(&nd, &file, op, flags | LOOKUP_REVAL); restore_nameidata(); putname(filename); - return file; + return unlikely(err) ? ERR_PTR(err) : file; } static struct dentry *filename_create(int dfd, struct filename *name,