mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/2] implement OA2_INHERIT_CRED flag for openat2()
@ 2024-04-23 10:40 Stas Sergeev
  2024-04-23 10:40 ` [PATCH 1/2] fs: reorganize path_openat() Stas Sergeev
  2024-04-23 10:40 ` [PATCH 2/2] openat2: add OA2_INHERIT_CRED flag Stas Sergeev
  0 siblings, 2 replies; 14+ messages in thread
From: Stas Sergeev @ 2024-04-23 10:40 UTC (permalink / raw)
  To: linux-kernel; +Cc: Stas Sergeev

This patch-set implements the OA2_INHERIT_CRED flag for openat2() syscall.
It is needed to perform an open operation with the creds that were in
effect when the dir_fd was opened. This allows the process to pre-open
some dirs and switch eUID (and other UIDs/GIDs) to the less-privileged
user, while still retaining the possibility to open/create files within
the pre-opened directory set.

Changes in v2:
- capture full struct cred instead of just fsuid/fsgid.
  Suggested by Stefan Metzmacher <metze@samba.org>


Stas Sergeev (2):
  fs: reorganize path_openat()
  openat2: add OA2_INHERIT_CRED flag

 fs/internal.h                |  2 +-
 fs/namei.c                   | 52 +++++++++++++++++++++++++++++-------
 fs/open.c                    |  2 +-
 include/linux/fcntl.h        |  2 ++
 include/uapi/linux/openat2.h |  3 +++
 5 files changed, 50 insertions(+), 11 deletions(-)

-- 
2.44.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/2] fs: reorganize path_openat()
  2024-04-23 10:40 [PATCH v2 0/2] implement OA2_INHERIT_CRED flag for openat2() Stas Sergeev
@ 2024-04-23 10:40 ` Stas Sergeev
  2024-04-23 10:40 ` [PATCH 2/2] openat2: add OA2_INHERIT_CRED flag Stas Sergeev
  1 sibling, 0 replies; 14+ messages in thread
From: Stas Sergeev @ 2024-04-23 10:40 UTC (permalink / raw)
  To: linux-kernel
  Cc: Stas Sergeev, Eric Biederman, Alexander Viro, Christian Brauner,
	Jan Kara, Andy Lutomirski, linux-fsdevel

This patch moves the call to alloc_empty_file() below the call to
path_init(). That changes is needed for the next patch, which adds
a cred override for alloc_empty_file(). The needed cred info is only
available after the call to path_init().

No functional changes are intended by that patch.

Signed-off-by: Stas Sergeev <stsp2@yandex.ru>

CC: Eric Biederman <ebiederm@xmission.com>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Christian Brauner <brauner@kernel.org>
CC: Jan Kara <jack@suse.cz>
CC: Andy Lutomirski <luto@kernel.org>
CC: linux-fsdevel@vger.kernel.org
CC: linux-kernel@vger.kernel.org
---
 fs/namei.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index c5b2a25be7d0..2fde2c320ae9 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3782,22 +3782,30 @@ static struct file *path_openat(struct nameidata *nd,
 	struct file *file;
 	int error;
 
-	file = alloc_empty_file(op->open_flag, current_cred());
-	if (IS_ERR(file))
-		return file;
-
-	if (unlikely(file->f_flags & __O_TMPFILE)) {
+	if (unlikely(op->open_flag & __O_TMPFILE)) {
+		file = alloc_empty_file(op->open_flag, current_cred());
+		if (IS_ERR(file))
+			return file;
 		error = do_tmpfile(nd, flags, op, file);
-	} else if (unlikely(file->f_flags & O_PATH)) {
+	} else if (unlikely(op->open_flag & O_PATH)) {
+		file = alloc_empty_file(op->open_flag, current_cred());
+		if (IS_ERR(file))
+			return file;
 		error = do_o_path(nd, flags, file);
 	} else {
 		const char *s = path_init(nd, flags);
-		while (!(error = link_path_walk(s, nd)) &&
-		       (s = open_last_lookups(nd, file, op)) != NULL)
-			;
+		file = alloc_empty_file(op->open_flag, current_cred());
+		error = PTR_ERR_OR_ZERO(file);
+		if (!error) {
+			while (!(error = link_path_walk(s, nd)) &&
+			       (s = open_last_lookups(nd, file, op)) != NULL)
+				;
+		}
 		if (!error)
 			error = do_open(nd, file, op);
 		terminate_walk(nd);
+		if (IS_ERR(file))
+			return file;
 	}
 	if (likely(!error)) {
 		if (likely(file->f_mode & FMODE_OPENED))
-- 
2.44.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/2] openat2: add OA2_INHERIT_CRED flag
  2024-04-23 10:40 [PATCH v2 0/2] implement OA2_INHERIT_CRED flag for openat2() Stas Sergeev
  2024-04-23 10:40 ` [PATCH 1/2] fs: reorganize path_openat() Stas Sergeev
@ 2024-04-23 10:40 ` Stas Sergeev
  1 sibling, 0 replies; 14+ messages in thread
From: Stas Sergeev @ 2024-04-23 10:40 UTC (permalink / raw)
  To: linux-kernel
  Cc: Stas Sergeev, Stefan Metzmacher, Eric Biederman, Alexander Viro,
	Andy Lutomirski, Christian Brauner, Jan Kara, Jeff Layton,
	Chuck Lever, Alexander Aring, linux-fsdevel, Paolo Bonzini,
	Christian Göttsche

This flag performs the open operation with the credentials that
were in effect when dir_fd was opened.
This allows the process to pre-open some directories and then
change eUID (and all other UIDs/GIDs) to a less-privileged user,
retaining the ability to open/create files within these directories.

Design goal:
The idea is to provide a very light-weight sandboxing, where the
process, without the use of any heavy-weight techniques like chroot
within namespaces, can restrict the access to the set of pre-opened
directories.
This patch is just a first step to such sandboxing. If things go
well, in the future the same extension can be added to more syscalls.
These should include at least unlinkat(), renameat2() and the
not-yet-upstreamed setxattrat().

Security considerations:
To avoid sandboxing escape, this patch makes sure the restricted
lookup modes are used. Namely, RESOLVE_BENEATH or RESOLVE_IN_ROOT.
To avoid leaking creds across exec, this patch requires O_CLOEXEC
flag on a directory.

Use cases:
Virtual machines that deal with untrusted code, can use that
instead of a more heavy-weighted approaches.
Currently the approach is being tested on a dosemu2 VM.

Signed-off-by: Stas Sergeev <stsp2@yandex.ru>

CC: Stefan Metzmacher <metze@samba.org>
CC: Eric Biederman <ebiederm@xmission.com>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Andy Lutomirski <luto@kernel.org>
CC: Christian Brauner <brauner@kernel.org>
CC: Jan Kara <jack@suse.cz>
CC: Jeff Layton <jlayton@kernel.org>
CC: Chuck Lever <chuck.lever@oracle.com>
CC: Alexander Aring <alex.aring@gmail.com>
CC: linux-fsdevel@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Christian Göttsche <cgzones@googlemail.com>
---
 fs/internal.h                |  2 +-
 fs/namei.c                   | 30 ++++++++++++++++++++++++++++--
 fs/open.c                    |  2 +-
 include/linux/fcntl.h        |  2 ++
 include/uapi/linux/openat2.h |  3 +++
 5 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index 7ca738904e34..692b53b19aad 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -169,7 +169,7 @@ static inline void sb_end_ro_state_change(struct super_block *sb)
  * open.c
  */
 struct open_flags {
-	int open_flag;
+	u64 open_flag;
 	umode_t mode;
 	int acc_mode;
 	int intent;
diff --git a/fs/namei.c b/fs/namei.c
index 2fde2c320ae9..0e0f2e32ef02 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -586,6 +586,7 @@ struct nameidata {
 	int		dfd;
 	vfsuid_t	dir_vfsuid;
 	umode_t		dir_mode;
+	const struct cred *dir_open_cred;
 } __randomize_layout;
 
 #define ND_ROOT_PRESET 1
@@ -695,6 +696,7 @@ static void terminate_walk(struct nameidata *nd)
 	nd->depth = 0;
 	nd->path.mnt = NULL;
 	nd->path.dentry = NULL;
+	put_cred(nd->dir_open_cred);
 }
 
 /* path_put is needed afterwards regardless of success or failure */
@@ -2414,6 +2416,7 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
 			get_fs_pwd(current->fs, &nd->path);
 			nd->inode = nd->path.dentry->d_inode;
 		}
+		nd->dir_open_cred = get_current_cred();
 	} else {
 		/* Caller must check execute permissions on the starting path component */
 		struct fd f = fdget_raw(nd->dfd);
@@ -2437,6 +2440,7 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
 			path_get(&nd->path);
 			nd->inode = nd->path.dentry->d_inode;
 		}
+		nd->dir_open_cred = get_cred(f.file->f_cred);
 		fdput(f);
 	}
 
@@ -3794,8 +3798,28 @@ static struct file *path_openat(struct nameidata *nd,
 		error = do_o_path(nd, flags, file);
 	} else {
 		const char *s = path_init(nd, flags);
-		file = alloc_empty_file(op->open_flag, current_cred());
-		error = PTR_ERR_OR_ZERO(file);
+		const struct cred *old_cred = NULL;
+
+		error = 0;
+		if (op->open_flag & OA2_INHERIT_CRED) {
+			/* Make sure to work only with restricted
+			 * look-up modes.
+			 */
+			if (!(nd->flags & (LOOKUP_BENEATH | LOOKUP_IN_ROOT)))
+				error = -EPERM;
+			/* Only work with O_CLOEXEC dirs. */
+			if (!get_close_on_exec(nd->dfd))
+				error = -EPERM;
+
+			if (!error)
+				old_cred = override_creds(nd->dir_open_cred);
+		}
+		if (!error) {
+			file = alloc_empty_file(op->open_flag, current_cred());
+			error = PTR_ERR_OR_ZERO(file);
+		} else {
+			file = ERR_PTR(error);
+		}
 		if (!error) {
 			while (!(error = link_path_walk(s, nd)) &&
 			       (s = open_last_lookups(nd, file, op)) != NULL)
@@ -3803,6 +3827,8 @@ static struct file *path_openat(struct nameidata *nd,
 		}
 		if (!error)
 			error = do_open(nd, file, op);
+		if (old_cred)
+			revert_creds(old_cred);
 		terminate_walk(nd);
 		if (IS_ERR(file))
 			return file;
diff --git a/fs/open.c b/fs/open.c
index ee8460c83c77..6be013182a35 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1225,7 +1225,7 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
 	 * values before calling build_open_flags(), but openat2(2) checks all
 	 * of its arguments.
 	 */
-	if (flags & ~VALID_OPEN_FLAGS)
+	if (flags & ~VALID_OPENAT2_FLAGS)
 		return -EINVAL;
 	if (how->resolve & ~VALID_RESOLVE_FLAGS)
 		return -EINVAL;
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index a332e79b3207..b71f8b162102 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -12,6 +12,8 @@
 	 FASYNC	| O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \
 	 O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)
 
+#define VALID_OPENAT2_FLAGS (VALID_OPEN_FLAGS | OA2_INHERIT_CRED)
+
 /* List of all valid flags for the how->resolve argument: */
 #define VALID_RESOLVE_FLAGS \
 	(RESOLVE_NO_XDEV | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS | \
diff --git a/include/uapi/linux/openat2.h b/include/uapi/linux/openat2.h
index a5feb7604948..cdd676a10b62 100644
--- a/include/uapi/linux/openat2.h
+++ b/include/uapi/linux/openat2.h
@@ -40,4 +40,7 @@ struct open_how {
 					return -EAGAIN if that's not
 					possible. */
 
+/* openat2-specific flags go to upper 4 bytes. */
+#define OA2_INHERIT_CRED		(1ULL << 32)
+
 #endif /* _UAPI_LINUX_OPENAT2_H */
-- 
2.44.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] fs: reorganize path_openat()
  2024-04-24 10:52 ` [PATCH 1/2] fs: reorganize path_openat() Stas Sergeev
@ 2024-04-25  8:13   ` kernel test robot
  0 siblings, 0 replies; 14+ messages in thread
From: kernel test robot @ 2024-04-25  8:13 UTC (permalink / raw)
  To: Stas Sergeev
  Cc: oe-lkp, lkp, Eric Biederman, Alexander Viro, Christian Brauner,
	Jan Kara, Andy Lutomirski, David Laight, linux-fsdevel,
	linux-kernel, Stas Sergeev, Stefan Metzmacher, Jeff Layton,
	Chuck Lever, Alexander Aring, linux-api, Paolo Bonzini,
	Christian Göttsche, oliver.sang



Hello,

kernel test robot noticed "BUG:sleeping_function_called_from_invalid_context_at_include/linux/sched/mm.h" on:

commit: 831d3c6cc6f05873e33f4aaebafbb9c27618ea0b ("[PATCH 1/2] fs: reorganize path_openat()")
url: https://github.com/intel-lab-lkp/linux/commits/Stas-Sergeev/fs-reorganize-path_openat/20240424-185527
base: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git 9d1ddab261f3e2af7c384dc02238784ce0cf9f98
patch link: https://lore.kernel.org/all/20240424105248.189032-2-stsp2@yandex.ru/
patch subject: [PATCH 1/2] fs: reorganize path_openat()

in testcase: boot

compiler: clang-17
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G

(please refer to attached dmesg/kmsg for entire log/backtrace)


+-------------------------------------------------------------------------------+------------+------------+
|                                                                               | 9d1ddab261 | 831d3c6cc6 |
+-------------------------------------------------------------------------------+------------+------------+
| boot_successes                                                                | 6          | 0          |
| boot_failures                                                                 | 0          | 6          |
| BUG:sleeping_function_called_from_invalid_context_at_include/linux/sched/mm.h | 0          | 6          |
+-------------------------------------------------------------------------------+------------+------------+


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202404251525.39b4af4e-lkp@intel.com


[    0.591465][   T33] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:315
[    0.592508][   T33] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 33, name: kworker/u8:2
[    0.593515][   T33] preempt_count: 0, expected: 0
[    0.594071][   T33] RCU nest depth: 1, expected: 0
[    0.594633][   T33] CPU: 0 PID: 33 Comm: kworker/u8:2 Not tainted 6.9.0-rc5-00037-g831d3c6cc6f0 #1
[    0.595637][   T33] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[    0.596216][   T33] Workqueue: async async_run_entry_fn
[    0.596216][   T33] Call Trace:
[    0.596216][   T33]  <TASK>
[ 0.596216][ T33] dump_stack_lvl (lib/dump_stack.c:116) 
[ 0.596216][ T33] __might_resched (kernel/sched/core.c:10198) 
[ 0.596216][ T33] kmem_cache_alloc (include/linux/kernel.h:73 include/linux/sched/mm.h:315 mm/slub.c:3746 mm/slub.c:3827 mm/slub.c:3852) 
[ 0.596216][ T33] alloc_empty_file (fs/file_table.c:203) 
[ 0.596216][ T33] path_openat (fs/namei.c:3796) 
[ 0.596216][ T33] do_filp_open (fs/namei.c:3833) 
[ 0.596216][ T33] file_open_name (fs/open.c:1352) 
[ 0.596216][ T33] filp_open (fs/open.c:1371) 
[ 0.596216][ T33] do_name (init/initramfs.c:373) 
[ 0.596216][ T33] flush_buffer (init/initramfs.c:452 init/initramfs.c:464) 
[ 0.596216][ T33] ? __pfx_flush_buffer (init/initramfs.c:458) 
[ 0.596216][ T33] __gunzip (lib/decompress_inflate.c:161) 
[ 0.596216][ T33] ? __pfx_nofill (lib/decompress_inflate.c:37) 
[ 0.596216][ T33] unpack_to_rootfs (init/initramfs.c:520) 
[ 0.596216][ T33] ? __pfx_error (init/initramfs.c:59) 
[ 0.596216][ T33] do_populate_rootfs (init/initramfs.c:714) 
[ 0.596216][ T33] async_run_entry_fn (kernel/async.c:136) 
[ 0.596216][ T33] process_scheduled_works (kernel/workqueue.c:3259) 
[ 0.596216][ T33] worker_thread (include/linux/list.h:373 kernel/workqueue.c:955 kernel/workqueue.c:3417) 
[ 0.596216][ T33] ? __pfx_worker_thread (kernel/workqueue.c:3362) 
[ 0.596216][ T33] kthread (kernel/kthread.c:390) 
[ 0.596216][ T33] ? __pfx_kthread (kernel/kthread.c:341) 
[ 0.596216][ T33] ret_from_fork (arch/x86/kernel/process.c:153) 
[ 0.596216][ T33] ? __pfx_kthread (kernel/kthread.c:341) 
[ 0.596216][ T33] ret_from_fork_asm (arch/x86/entry/entry_64.S:257) 
[    0.596216][   T33]  </TASK>
[    1.603321][   T33] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:315
[    1.604448][   T33] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 33, name: kworker/u8:2
[    1.605466][   T33] preempt_count: 0, expected: 0
[    1.606028][   T33] RCU nest depth: 1, expected: 0
[    1.606599][   T33] CPU: 0 PID: 33 Comm: kworker/u8:2 Tainted: G        W          6.9.0-rc5-00037-g831d3c6cc6f0 #1
[    1.607761][   T33] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[    1.608136][   T33] Workqueue: async async_run_entry_fn
[    1.608136][   T33] Call Trace:
[    1.608136][   T33]  <TASK>
[ 1.608136][ T33] dump_stack_lvl (lib/dump_stack.c:116) 
[ 1.608136][ T33] __might_resched (kernel/sched/core.c:10198) 
[ 1.608136][ T33] kmem_cache_alloc (include/linux/kernel.h:73 include/linux/sched/mm.h:315 mm/slub.c:3746 mm/slub.c:3827 mm/slub.c:3852) 
[ 1.608136][ T33] alloc_empty_file (fs/file_table.c:203) 
[ 1.608136][ T33] path_openat (fs/namei.c:3796) 
[ 1.608136][ T33] do_filp_open (fs/namei.c:3833) 
[ 1.608136][ T33] file_open_name (fs/open.c:1352) 
[ 1.608136][ T33] filp_open (fs/open.c:1371) 
[ 1.608136][ T33] do_name (init/initramfs.c:373) 
[ 1.608136][ T33] flush_buffer (init/initramfs.c:452 init/initramfs.c:464) 
[ 1.608136][ T33] ? __pfx_flush_buffer (init/initramfs.c:458) 
[ 1.608136][ T33] __gunzip (lib/decompress_inflate.c:161) 
[ 1.608136][ T33] ? __pfx_nofill (lib/decompress_inflate.c:37) 
[ 1.608136][ T33] unpack_to_rootfs (init/initramfs.c:520) 
[ 1.608136][ T33] ? __pfx_error (init/initramfs.c:59) 
[ 1.608136][ T33] do_populate_rootfs (init/initramfs.c:714) 
[ 1.608136][ T33] async_run_entry_fn (kernel/async.c:136) 
[ 1.608136][ T33] process_scheduled_works (kernel/workqueue.c:3259) 
[ 1.608136][ T33] worker_thread (include/linux/list.h:373 kernel/workqueue.c:955 kernel/workqueue.c:3417) 
[ 1.608136][ T33] ? __pfx_worker_thread (kernel/workqueue.c:3362) 
[ 1.608136][ T33] kthread (kernel/kthread.c:390) 
[ 1.608136][ T33] ? __pfx_kthread (kernel/kthread.c:341) 
[ 1.608136][ T33] ret_from_fork (arch/x86/kernel/process.c:153) 
[ 1.608136][ T33] ? __pfx_kthread (kernel/kthread.c:341) 
[ 1.608136][ T33] ret_from_fork_asm (arch/x86/entry/entry_64.S:257) 
[    1.608136][   T33]  </TASK>
[    2.602317][   T33] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:315
[    2.603414][   T33] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 33, name: kworker/u8:2
[    2.604433][   T33] preempt_count: 0, expected: 0
[    2.604985][   T33] RCU nest depth: 1, expected: 0
[    2.605547][   T33] CPU: 0 PID: 33 Comm: kworker/u8:2 Tainted: G        W          6.9.0-rc5-00037-g831d3c6cc6f0 #1
[    2.606689][   T33] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[    2.607825][   T33] Workqueue: async async_run_entry_fn
[    2.608140][   T33] Call Trace:
[    2.608140][   T33]  <TASK>
[ 2.608140][ T33] dump_stack_lvl (lib/dump_stack.c:116) 
[ 2.608140][ T33] __might_resched (kernel/sched/core.c:10198) 
[ 2.608140][ T33] kmem_cache_alloc (include/linux/kernel.h:73 include/linux/sched/mm.h:315 mm/slub.c:3746 mm/slub.c:3827 mm/slub.c:3852) 
[ 2.608140][ T33] alloc_empty_file (fs/file_table.c:203) 
[ 2.608140][ T33] path_openat (fs/namei.c:3796) 
[ 2.608140][ T33] do_filp_open (fs/namei.c:3833) 
[ 2.608140][ T33] file_open_name (fs/open.c:1352) 
[ 2.608140][ T33] filp_open (fs/open.c:1371) 
[ 2.608140][ T33] do_name (init/initramfs.c:373) 
[ 2.608140][ T33] flush_buffer (init/initramfs.c:452 init/initramfs.c:464) 
[ 2.608140][ T33] ? __pfx_flush_buffer (init/initramfs.c:458) 
[ 2.608140][ T33] __gunzip (lib/decompress_inflate.c:161) 
[ 2.608140][ T33] ? __pfx_nofill (lib/decompress_inflate.c:37) 
[ 2.608140][ T33] unpack_to_rootfs (init/initramfs.c:520) 
[ 2.608140][ T33] ? __pfx_error (init/initramfs.c:59) 
[ 2.608140][ T33] do_populate_rootfs (init/initramfs.c:714) 
[ 2.608140][ T33] async_run_entry_fn (kernel/async.c:136) 
[ 2.608140][ T33] process_scheduled_works (kernel/workqueue.c:3259) 
[ 2.608140][ T33] worker_thread (include/linux/list.h:373 kernel/workqueue.c:955 kernel/workqueue.c:3417) 
[ 2.608140][ T33] ? __pfx_worker_thread (kernel/workqueue.c:3362) 
[ 2.608140][ T33] kthread (kernel/kthread.c:390) 
[ 2.608140][ T33] ? __pfx_kthread (kernel/kthread.c:341) 
[ 2.608140][ T33] ret_from_fork (arch/x86/kernel/process.c:153) 
[ 2.608140][ T33] ? __pfx_kthread (kernel/kthread.c:341) 
[ 2.608140][ T33] ret_from_fork_asm (arch/x86/entry/entry_64.S:257) 
[    2.608140][   T33]  </TASK>
[    3.648001][   T33] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:315
[    3.649103][   T33] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 33, name: kworker/u8:2
[    3.650109][   T33] preempt_count: 0, expected: 0
[    3.650660][   T33] RCU nest depth: 1, expected: 0
[    3.651223][   T33] CPU: 0 PID: 33 Comm: kworker/u8:2 Tainted: G        W          6.9.0-rc5-00037-g831d3c6cc6f0 #1
[    3.651979][   T33] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[    3.651979][   T33] Workqueue: async async_run_entry_fn
[    3.651979][   T33] Call Trace:
[    3.651979][   T33]  <TASK>
[ 3.651979][ T33] dump_stack_lvl (lib/dump_stack.c:116) 
[ 3.651979][ T33] __might_resched (kernel/sched/core.c:10198) 
[ 3.651979][ T33] kmem_cache_alloc (include/linux/kernel.h:73 include/linux/sched/mm.h:315 mm/slub.c:3746 mm/slub.c:3827 mm/slub.c:3852) 
[ 3.651979][ T33] alloc_empty_file (fs/file_table.c:203) 
[ 3.651979][ T33] path_openat (fs/namei.c:3796) 
[ 3.651979][ T33] do_filp_open (fs/namei.c:3833) 
[ 3.651979][ T33] file_open_name (fs/open.c:1352) 
[ 3.651979][ T33] filp_open (fs/open.c:1371) 
[ 3.651979][ T33] do_name (init/initramfs.c:373) 
[ 3.651979][ T33] flush_buffer (init/initramfs.c:452 init/initramfs.c:464) 
[ 3.651979][ T33] ? __pfx_flush_buffer (init/initramfs.c:458) 
[ 3.651979][ T33] __gunzip (lib/decompress_inflate.c:161) 
[ 3.651979][ T33] ? __pfx_nofill (lib/decompress_inflate.c:37) 
[ 3.651979][ T33] unpack_to_rootfs (init/initramfs.c:520) 
[ 3.651979][ T33] ? __pfx_error (init/initramfs.c:59) 
[ 3.651979][ T33] do_populate_rootfs (init/initramfs.c:714) 
[ 3.651979][ T33] async_run_entry_fn (kernel/async.c:136) 
[ 3.651979][ T33] process_scheduled_works (kernel/workqueue.c:3259) 
[ 3.651979][ T33] worker_thread (include/linux/list.h:373 kernel/workqueue.c:955 kernel/workqueue.c:3417) 
[ 3.651979][ T33] ? __pfx_worker_thread (kernel/workqueue.c:3362) 
[ 3.651979][ T33] kthread (kernel/kthread.c:390) 
[ 3.651979][ T33] ? __pfx_kthread (kernel/kthread.c:341) 
[ 3.651979][ T33] ret_from_fork (arch/x86/kernel/process.c:153) 
[ 3.651979][ T33] ? __pfx_kthread (kernel/kthread.c:341) 
[ 3.651979][ T33] ret_from_fork_asm (arch/x86/entry/entry_64.S:257) 
[    3.651979][   T33]  </TASK>
[    3.705833][   T33] Freeing initrd memory: 185612K



The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20240425/202404251525.39b4af4e-lkp@intel.com



-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] fs: reorganize path_openat()
  2024-04-24 15:07     ` David Laight
@ 2024-04-24 17:41       ` stsp
  0 siblings, 0 replies; 14+ messages in thread
From: stsp @ 2024-04-24 17:41 UTC (permalink / raw)
  To: David Laight, linux-kernel

24.04.2024 18:07, David Laight пишет:
> From: stsp
>> Sent: 24 April 2024 11:59
> ...
>> Posted v4 with this code verbatim.
> Nope - you've just posted a different version of the 'v1' patch.
> Should be [PATCH v4 1/2]
I simply use `git format-patch`
and `git send-email`.
Are all those customizations needs
to be done by hands?

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH 1/2] fs: reorganize path_openat()
  2024-04-24 10:58   ` stsp
@ 2024-04-24 15:07     ` David Laight
  2024-04-24 17:41       ` stsp
  0 siblings, 1 reply; 14+ messages in thread
From: David Laight @ 2024-04-24 15:07 UTC (permalink / raw)
  To: 'stsp', linux-kernel
  Cc: Eric Biederman, Alexander Viro, Christian Brauner, Jan Kara,
	Andy Lutomirski, linux-fsdevel

From: stsp
> Sent: 24 April 2024 11:59
...
> Posted v4 with this code verbatim.

Nope - you've just posted a different version of the 'v1' patch.
Should be [PATCH v4 1/2]

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] fs: reorganize path_openat()
  2024-04-24  9:17 ` David Laight
  2024-04-24  9:24   ` stsp
@ 2024-04-24 10:58   ` stsp
  2024-04-24 15:07     ` David Laight
  1 sibling, 1 reply; 14+ messages in thread
From: stsp @ 2024-04-24 10:58 UTC (permalink / raw)
  To: David Laight, linux-kernel
  Cc: Eric Biederman, Alexander Viro, Christian Brauner, Jan Kara,
	Andy Lutomirski, linux-fsdevel

24.04.2024 12:17, David Laight пишет:
> You probably ought to merge the two 'unlikely' tests.
> Otherwise there'll be two conditionals in the 'hot path'.
> (There probably always were.)
> So something like:
> 	if (unlikely(op->open_flag & (__O_TMPFILE | O_PATH))) {
> 		file = alloc_empty_file(op->open_flag, current_cred());
> 		if (IS_ERR(file))
> 			return file;
> 		if (op->open_flag & __O_TMFILE)
> 			error = do_tmpfile(nd, flags, op, file);
> 		else
> 			error = do_o_path(nd, flags, file);
> 	} else {

Posted v4 with this code verbatim.

> Copying op->open_flag to a local may also generate better code.
Done this as well.

Thank you.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/2] fs: reorganize path_openat()
  2024-04-24 10:52 [PATCH v4 0/2] implement OA2_INHERIT_CRED flag for openat2() Stas Sergeev
@ 2024-04-24 10:52 ` Stas Sergeev
  2024-04-25  8:13   ` kernel test robot
  0 siblings, 1 reply; 14+ messages in thread
From: Stas Sergeev @ 2024-04-24 10:52 UTC (permalink / raw)
  To: linux-kernel
  Cc: Stas Sergeev, Stefan Metzmacher, Eric Biederman, Alexander Viro,
	Andy Lutomirski, Christian Brauner, Jan Kara, Jeff Layton,
	Chuck Lever, Alexander Aring, David Laight, linux-fsdevel,
	linux-api, Paolo Bonzini, Christian Göttsche

This patch moves the call to alloc_empty_file() below the call to
path_init(). That changes is needed for the next patch, which adds
a cred override for alloc_empty_file(). The needed cred info is only
available after the call to path_init().

No functional changes are intended by that patch.

Signed-off-by: Stas Sergeev <stsp2@yandex.ru>

CC: Eric Biederman <ebiederm@xmission.com>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Christian Brauner <brauner@kernel.org>
CC: Jan Kara <jack@suse.cz>
CC: Andy Lutomirski <luto@kernel.org>
CC: David Laight <David.Laight@ACULAB.COM>
CC: linux-fsdevel@vger.kernel.org
CC: linux-kernel@vger.kernel.org
---
 fs/namei.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index c5b2a25be7d0..413eef134234 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3781,23 +3781,30 @@ static struct file *path_openat(struct nameidata *nd,
 {
 	struct file *file;
 	int error;
+	u64 open_flags = op->open_flag;
 
-	file = alloc_empty_file(op->open_flag, current_cred());
-	if (IS_ERR(file))
-		return file;
-
-	if (unlikely(file->f_flags & __O_TMPFILE)) {
-		error = do_tmpfile(nd, flags, op, file);
-	} else if (unlikely(file->f_flags & O_PATH)) {
-		error = do_o_path(nd, flags, file);
+	if (unlikely(open_flags & (__O_TMPFILE | O_PATH))) {
+		file = alloc_empty_file(open_flags, current_cred());
+		if (IS_ERR(file))
+			return file;
+		if (open_flags & __O_TMPFILE)
+			error = do_tmpfile(nd, flags, op, file);
+		else
+			error = do_o_path(nd, flags, file);
 	} else {
 		const char *s = path_init(nd, flags);
-		while (!(error = link_path_walk(s, nd)) &&
-		       (s = open_last_lookups(nd, file, op)) != NULL)
-			;
+		file = alloc_empty_file(open_flags, current_cred());
+		error = PTR_ERR_OR_ZERO(file);
+		if (!error) {
+			while (!(error = link_path_walk(s, nd)) &&
+			       (s = open_last_lookups(nd, file, op)) != NULL)
+				;
+		}
 		if (!error)
 			error = do_open(nd, file, op);
 		terminate_walk(nd);
+		if (IS_ERR(file))
+			return file;
 	}
 	if (likely(!error)) {
 		if (likely(file->f_mode & FMODE_OPENED))
-- 
2.44.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] fs: reorganize path_openat()
  2024-04-24  9:17 ` David Laight
@ 2024-04-24  9:24   ` stsp
  2024-04-24 10:58   ` stsp
  1 sibling, 0 replies; 14+ messages in thread
From: stsp @ 2024-04-24  9:24 UTC (permalink / raw)
  To: David Laight, linux-kernel
  Cc: Eric Biederman, Alexander Viro, Christian Brauner, Jan Kara,
	Andy Lutomirski, linux-fsdevel

24.04.2024 12:17, David Laight пишет:
> From: Stas Sergeev
>> Sent: 22 April 2024 09:45
> I seem to have 5 copies of this patch.....

Yep, its re-sent with every new iteartion,
but doesn't change by itself (the other
one changes).
Is there anything I can do to avoid
unneeded duplicates of an unchanged
patch?
Manually reduce Cc list until the patch
changes? That looks too much of a trouble
though.

> You probably ought to merge the two 'unlikely' tests.

Ok.


> Copying op->open_flag to a local may also generate better code.

Can't gcc deduce this on its own?
But ok, will do.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH 1/2] fs: reorganize path_openat()
  2024-04-22  8:45 Stas Sergeev
@ 2024-04-24  9:17 ` David Laight
  2024-04-24  9:24   ` stsp
  2024-04-24 10:58   ` stsp
  0 siblings, 2 replies; 14+ messages in thread
From: David Laight @ 2024-04-24  9:17 UTC (permalink / raw)
  To: 'Stas Sergeev', linux-kernel
  Cc: Eric Biederman, Alexander Viro, Christian Brauner, Jan Kara,
	Andy Lutomirski, linux-fsdevel

From: Stas Sergeev
> Sent: 22 April 2024 09:45

I seem to have 5 copies of this patch.....

> This patch moves the call to alloc_empty_file() below the call to
> path_init(). That changes is needed for the next patch, which adds
> a cred override for alloc_empty_file(). The needed cred info is only
> available after the call to path_init().
> 
> No functional changes are intended by that patch.
...
> ---
>  fs/namei.c | 26 +++++++++++++++++---------
>  1 file changed, 17 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/namei.c b/fs/namei.c
> index c5b2a25be7d0..2fde2c320ae9 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -3782,22 +3782,30 @@ static struct file *path_openat(struct nameidata *nd,
>  	struct file *file;
>  	int error;
> 
> -	file = alloc_empty_file(op->open_flag, current_cred());
> -	if (IS_ERR(file))
> -		return file;
> -
> -	if (unlikely(file->f_flags & __O_TMPFILE)) {
> +	if (unlikely(op->open_flag & __O_TMPFILE)) {
> +		file = alloc_empty_file(op->open_flag, current_cred());
> +		if (IS_ERR(file))
> +			return file;
>  		error = do_tmpfile(nd, flags, op, file);
> -	} else if (unlikely(file->f_flags & O_PATH)) {
> +	} else if (unlikely(op->open_flag & O_PATH)) {
> +		file = alloc_empty_file(op->open_flag, current_cred());
> +		if (IS_ERR(file))
> +			return file;
>  		error = do_o_path(nd, flags, file);

You probably ought to merge the two 'unlikely' tests.
Otherwise there'll be two conditionals in the 'hot path'.
(There probably always were.)
So something like:
	if (unlikely(op->open_flag & (__O_TMPFILE | O_PATH))) {
		file = alloc_empty_file(op->open_flag, current_cred());
		if (IS_ERR(file))
			return file;
		if (op->open_flag & __O_TMFILE)
			error = do_tmpfile(nd, flags, op, file);
		else
			error = do_o_path(nd, flags, file);
	} else {
Copying op->open_flag to a local may also generate better code.

	David
		
>  	} else {
>  		const char *s = path_init(nd, flags);
> -		while (!(error = link_path_walk(s, nd)) &&
> -		       (s = open_last_lookups(nd, file, op)) != NULL)
> -			;
> +		file = alloc_empty_file(op->open_flag, current_cred());
> +		error = PTR_ERR_OR_ZERO(file);
> +		if (!error) {
> +			while (!(error = link_path_walk(s, nd)) &&
> +			       (s = open_last_lookups(nd, file, op)) != NULL)
> +				;
> +		}
>  		if (!error)
>  			error = do_open(nd, file, op);
>  		terminate_walk(nd);
> +		if (IS_ERR(file))
> +			return file;
>  	}
>  	if (likely(!error)) {
>  		if (likely(file->f_mode & FMODE_OPENED))
> --
> 2.44.0
> 

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/2] fs: reorganize path_openat()
  2024-04-23 22:46 [PATCH v3 0/2] implement OA2_INHERIT_CRED flag for openat2() Stas Sergeev
@ 2024-04-23 22:46 ` Stas Sergeev
  0 siblings, 0 replies; 14+ messages in thread
From: Stas Sergeev @ 2024-04-23 22:46 UTC (permalink / raw)
  To: linux-kernel
  Cc: Stas Sergeev, Stefan Metzmacher, Eric Biederman, Alexander Viro,
	Andy Lutomirski, Christian Brauner, Jan Kara, Jeff Layton,
	Chuck Lever, Alexander Aring, linux-fsdevel, linux-api,
	Paolo Bonzini, Christian Göttsche

This patch moves the call to alloc_empty_file() below the call to
path_init(). That changes is needed for the next patch, which adds
a cred override for alloc_empty_file(). The needed cred info is only
available after the call to path_init().

No functional changes are intended by that patch.

Signed-off-by: Stas Sergeev <stsp2@yandex.ru>

CC: Eric Biederman <ebiederm@xmission.com>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Christian Brauner <brauner@kernel.org>
CC: Jan Kara <jack@suse.cz>
CC: Andy Lutomirski <luto@kernel.org>
CC: linux-fsdevel@vger.kernel.org
CC: linux-kernel@vger.kernel.org
---
 fs/namei.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index c5b2a25be7d0..2fde2c320ae9 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3782,22 +3782,30 @@ static struct file *path_openat(struct nameidata *nd,
 	struct file *file;
 	int error;
 
-	file = alloc_empty_file(op->open_flag, current_cred());
-	if (IS_ERR(file))
-		return file;
-
-	if (unlikely(file->f_flags & __O_TMPFILE)) {
+	if (unlikely(op->open_flag & __O_TMPFILE)) {
+		file = alloc_empty_file(op->open_flag, current_cred());
+		if (IS_ERR(file))
+			return file;
 		error = do_tmpfile(nd, flags, op, file);
-	} else if (unlikely(file->f_flags & O_PATH)) {
+	} else if (unlikely(op->open_flag & O_PATH)) {
+		file = alloc_empty_file(op->open_flag, current_cred());
+		if (IS_ERR(file))
+			return file;
 		error = do_o_path(nd, flags, file);
 	} else {
 		const char *s = path_init(nd, flags);
-		while (!(error = link_path_walk(s, nd)) &&
-		       (s = open_last_lookups(nd, file, op)) != NULL)
-			;
+		file = alloc_empty_file(op->open_flag, current_cred());
+		error = PTR_ERR_OR_ZERO(file);
+		if (!error) {
+			while (!(error = link_path_walk(s, nd)) &&
+			       (s = open_last_lookups(nd, file, op)) != NULL)
+				;
+		}
 		if (!error)
 			error = do_open(nd, file, op);
 		terminate_walk(nd);
+		if (IS_ERR(file))
+			return file;
 	}
 	if (likely(!error)) {
 		if (likely(file->f_mode & FMODE_OPENED))
-- 
2.44.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/2] fs: reorganize path_openat()
  2024-04-23 11:01 [PATCH v2 0/2] implement OA2_INHERIT_CRED flag for openat2() Stas Sergeev
@ 2024-04-23 11:01 ` Stas Sergeev
  0 siblings, 0 replies; 14+ messages in thread
From: Stas Sergeev @ 2024-04-23 11:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: Stas Sergeev, Stefan Metzmacher, Eric Biederman, Alexander Viro,
	Andy Lutomirski, Christian Brauner, Jan Kara, Jeff Layton,
	Chuck Lever, Alexander Aring, linux-fsdevel, linux-api,
	Paolo Bonzini, Christian Göttsche

This patch moves the call to alloc_empty_file() below the call to
path_init(). That changes is needed for the next patch, which adds
a cred override for alloc_empty_file(). The needed cred info is only
available after the call to path_init().

No functional changes are intended by that patch.

Signed-off-by: Stas Sergeev <stsp2@yandex.ru>

CC: Eric Biederman <ebiederm@xmission.com>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Christian Brauner <brauner@kernel.org>
CC: Jan Kara <jack@suse.cz>
CC: Andy Lutomirski <luto@kernel.org>
CC: linux-fsdevel@vger.kernel.org
CC: linux-kernel@vger.kernel.org
---
 fs/namei.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index c5b2a25be7d0..2fde2c320ae9 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3782,22 +3782,30 @@ static struct file *path_openat(struct nameidata *nd,
 	struct file *file;
 	int error;
 
-	file = alloc_empty_file(op->open_flag, current_cred());
-	if (IS_ERR(file))
-		return file;
-
-	if (unlikely(file->f_flags & __O_TMPFILE)) {
+	if (unlikely(op->open_flag & __O_TMPFILE)) {
+		file = alloc_empty_file(op->open_flag, current_cred());
+		if (IS_ERR(file))
+			return file;
 		error = do_tmpfile(nd, flags, op, file);
-	} else if (unlikely(file->f_flags & O_PATH)) {
+	} else if (unlikely(op->open_flag & O_PATH)) {
+		file = alloc_empty_file(op->open_flag, current_cred());
+		if (IS_ERR(file))
+			return file;
 		error = do_o_path(nd, flags, file);
 	} else {
 		const char *s = path_init(nd, flags);
-		while (!(error = link_path_walk(s, nd)) &&
-		       (s = open_last_lookups(nd, file, op)) != NULL)
-			;
+		file = alloc_empty_file(op->open_flag, current_cred());
+		error = PTR_ERR_OR_ZERO(file);
+		if (!error) {
+			while (!(error = link_path_walk(s, nd)) &&
+			       (s = open_last_lookups(nd, file, op)) != NULL)
+				;
+		}
 		if (!error)
 			error = do_open(nd, file, op);
 		terminate_walk(nd);
+		if (IS_ERR(file))
+			return file;
 	}
 	if (likely(!error)) {
 		if (likely(file->f_mode & FMODE_OPENED))
-- 
2.44.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/2] fs: reorganize path_openat()
  2024-04-23 10:48 [PATCH v2 0/2] implement OA2_INHERIT_CRED flag for openat2() Stas Sergeev
@ 2024-04-23 10:48 ` Stas Sergeev
  0 siblings, 0 replies; 14+ messages in thread
From: Stas Sergeev @ 2024-04-23 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Stas Sergeev, Stefan Metzmacher, Eric Biederman, Alexander Viro,
	Andy Lutomirski, Christian Brauner, Jan Kara, Jeff Layton,
	Chuck Lever, Alexander Aring, linux-fsdevel, Paolo Bonzini,
	Christian Göttsche

This patch moves the call to alloc_empty_file() below the call to
path_init(). That changes is needed for the next patch, which adds
a cred override for alloc_empty_file(). The needed cred info is only
available after the call to path_init().

No functional changes are intended by that patch.

Signed-off-by: Stas Sergeev <stsp2@yandex.ru>

CC: Eric Biederman <ebiederm@xmission.com>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Christian Brauner <brauner@kernel.org>
CC: Jan Kara <jack@suse.cz>
CC: Andy Lutomirski <luto@kernel.org>
CC: linux-fsdevel@vger.kernel.org
CC: linux-kernel@vger.kernel.org
---
 fs/namei.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index c5b2a25be7d0..2fde2c320ae9 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3782,22 +3782,30 @@ static struct file *path_openat(struct nameidata *nd,
 	struct file *file;
 	int error;
 
-	file = alloc_empty_file(op->open_flag, current_cred());
-	if (IS_ERR(file))
-		return file;
-
-	if (unlikely(file->f_flags & __O_TMPFILE)) {
+	if (unlikely(op->open_flag & __O_TMPFILE)) {
+		file = alloc_empty_file(op->open_flag, current_cred());
+		if (IS_ERR(file))
+			return file;
 		error = do_tmpfile(nd, flags, op, file);
-	} else if (unlikely(file->f_flags & O_PATH)) {
+	} else if (unlikely(op->open_flag & O_PATH)) {
+		file = alloc_empty_file(op->open_flag, current_cred());
+		if (IS_ERR(file))
+			return file;
 		error = do_o_path(nd, flags, file);
 	} else {
 		const char *s = path_init(nd, flags);
-		while (!(error = link_path_walk(s, nd)) &&
-		       (s = open_last_lookups(nd, file, op)) != NULL)
-			;
+		file = alloc_empty_file(op->open_flag, current_cred());
+		error = PTR_ERR_OR_ZERO(file);
+		if (!error) {
+			while (!(error = link_path_walk(s, nd)) &&
+			       (s = open_last_lookups(nd, file, op)) != NULL)
+				;
+		}
 		if (!error)
 			error = do_open(nd, file, op);
 		terminate_walk(nd);
+		if (IS_ERR(file))
+			return file;
 	}
 	if (likely(!error)) {
 		if (likely(file->f_mode & FMODE_OPENED))
-- 
2.44.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/2] fs: reorganize path_openat()
@ 2024-04-22  8:45 Stas Sergeev
  2024-04-24  9:17 ` David Laight
  0 siblings, 1 reply; 14+ messages in thread
From: Stas Sergeev @ 2024-04-22  8:45 UTC (permalink / raw)
  To: linux-kernel
  Cc: Stas Sergeev, Eric Biederman, Alexander Viro, Christian Brauner,
	Jan Kara, Andy Lutomirski, linux-fsdevel

This patch moves the call to alloc_empty_file() below the call to
path_init(). That changes is needed for the next patch, which adds
a cred override for alloc_empty_file(). The needed cred info is only
available after the call to path_init().

No functional changes are intended by that patch.

Signed-off-by: Stas Sergeev <stsp2@yandex.ru>

CC: Eric Biederman <ebiederm@xmission.com>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Christian Brauner <brauner@kernel.org>
CC: Jan Kara <jack@suse.cz>
CC: Andy Lutomirski <luto@kernel.org>
CC: linux-fsdevel@vger.kernel.org
CC: linux-kernel@vger.kernel.org
---
 fs/namei.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index c5b2a25be7d0..2fde2c320ae9 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3782,22 +3782,30 @@ static struct file *path_openat(struct nameidata *nd,
 	struct file *file;
 	int error;
 
-	file = alloc_empty_file(op->open_flag, current_cred());
-	if (IS_ERR(file))
-		return file;
-
-	if (unlikely(file->f_flags & __O_TMPFILE)) {
+	if (unlikely(op->open_flag & __O_TMPFILE)) {
+		file = alloc_empty_file(op->open_flag, current_cred());
+		if (IS_ERR(file))
+			return file;
 		error = do_tmpfile(nd, flags, op, file);
-	} else if (unlikely(file->f_flags & O_PATH)) {
+	} else if (unlikely(op->open_flag & O_PATH)) {
+		file = alloc_empty_file(op->open_flag, current_cred());
+		if (IS_ERR(file))
+			return file;
 		error = do_o_path(nd, flags, file);
 	} else {
 		const char *s = path_init(nd, flags);
-		while (!(error = link_path_walk(s, nd)) &&
-		       (s = open_last_lookups(nd, file, op)) != NULL)
-			;
+		file = alloc_empty_file(op->open_flag, current_cred());
+		error = PTR_ERR_OR_ZERO(file);
+		if (!error) {
+			while (!(error = link_path_walk(s, nd)) &&
+			       (s = open_last_lookups(nd, file, op)) != NULL)
+				;
+		}
 		if (!error)
 			error = do_open(nd, file, op);
 		terminate_walk(nd);
+		if (IS_ERR(file))
+			return file;
 	}
 	if (likely(!error)) {
 		if (likely(file->f_mode & FMODE_OPENED))
-- 
2.44.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2024-04-25  8:13 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-23 10:40 [PATCH v2 0/2] implement OA2_INHERIT_CRED flag for openat2() Stas Sergeev
2024-04-23 10:40 ` [PATCH 1/2] fs: reorganize path_openat() Stas Sergeev
2024-04-23 10:40 ` [PATCH 2/2] openat2: add OA2_INHERIT_CRED flag Stas Sergeev
  -- strict thread matches above, loose matches on Subject: below --
2024-04-24 10:52 [PATCH v4 0/2] implement OA2_INHERIT_CRED flag for openat2() Stas Sergeev
2024-04-24 10:52 ` [PATCH 1/2] fs: reorganize path_openat() Stas Sergeev
2024-04-25  8:13   ` kernel test robot
2024-04-23 22:46 [PATCH v3 0/2] implement OA2_INHERIT_CRED flag for openat2() Stas Sergeev
2024-04-23 22:46 ` [PATCH 1/2] fs: reorganize path_openat() Stas Sergeev
2024-04-23 11:01 [PATCH v2 0/2] implement OA2_INHERIT_CRED flag for openat2() Stas Sergeev
2024-04-23 11:01 ` [PATCH 1/2] fs: reorganize path_openat() Stas Sergeev
2024-04-23 10:48 [PATCH v2 0/2] implement OA2_INHERIT_CRED flag for openat2() Stas Sergeev
2024-04-23 10:48 ` [PATCH 1/2] fs: reorganize path_openat() Stas Sergeev
2024-04-22  8:45 Stas Sergeev
2024-04-24  9:17 ` David Laight
2024-04-24  9:24   ` stsp
2024-04-24 10:58   ` stsp
2024-04-24 15:07     ` David Laight
2024-04-24 17:41       ` stsp

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®