Re: [PATCH] idmapped-mounts: probe O_TMPFILE support with the caller's mapped id
Zizhi Wo <[email protected]>
| Newsgroups | org.kernel.vger.fstests |
|---|---|
| Message-ID | <[email protected]> |
在 2026/8/11 4:40, Zorro Lang 写道: > On Thu, Aug 06, 2026 at 02:11:55PM +0800, Zizhi Wo wrote: >> friendly ping... > > Hi Zizhi, actually I'm waiting for the fix from vfs list. Sorry, I hadn't noticed that this issue had already been discussed and fixed by the community. Thanks for pointing it out. Thanks, Zizhi Wo > > Hi Christian, > > Could you please take a look at this issue? Quite a few people have submitted > patches trying to fix this test issue. Given that you are the authority on > this topic and previously sent a patchset [1] to fix this kind of issue, I think > accepting your patch would be the best approach to stay aligned with upstream > VFS. Christoph also metioned that [2] last time. I don't want to make this issue > fixing any more complicated. Could you please provide your review point or > rebase your fix on the latest fstests for-next branch, we'll review it ASAP. > > [1] > https://lore.kernel.org/fstests/[email protected]/ > > [2] > https://lore.kernel.org/fstests/[email protected]/ > > Thanks, > Zorro > >> >> 在 2026/7/31 17:02, Zizhi Wo 写道: >>> From: Zizhi Wo <[email protected]> >>> >>> Kernel commit 539dce114465 ("fs: refuse O_TMPFILE creation with an >>> unmapped fsuid or fsgid") made vfs_tmpfile() return -EOVERFLOW when the >>> caller's fsuid/fsgid has no mapping in the filesystem's user namespace >>> after applying the mount's idmapping. This is a no-op on non-idmapped >>> mounts and only takes effect on an idmapped mount that does not map the >>> caller. >>> >>> The idmapped-mount testcases behind generic/696 and generic/697 build an >>> idmapping (e.g. "0 10000 10000") that covers host uid 10000-19999 but >>> not uid 0, then call openat_tmpfile_supported() from the parent process >>> that is still real root (fsuid 0). The probe now gets -EOVERFLOW, falls >>> into the log_errno() branch, and prints >>> >>> utils.c: 928: openat_tmpfile_supported - Value too large for defined \ >>> data type - failure: create >>> >>> to stderr. Both testcases expect "Silence is golden", so this spurious >>> output fails them, even though the kernel behavior is correct and the >>> testcases' own assertions all pass. >>> >>> Move each openat_tmpfile_supported() call into the child, after >>> switch_ids()/switch_userns(), so it probes with the mapped identity the >>> tmpfile section uses. Silencing EOVERFLOW in openat_tmpfile_supported() >>> would make it indistinguishable whether the idmapping genuinely has no >>> mapping for any caller, or the probe just ran in the unmapped parent before >>> the switch. >>> >>> Signed-off-by: Zizhi Wo <[email protected]> >>> --- >>> src/vfs/idmapped-mounts.c | 32 ++++++++++++++++++++------------ >>> 1 file changed, 20 insertions(+), 12 deletions(-) >>> >>> diff --git a/src/vfs/idmapped-mounts.c b/src/vfs/idmapped-mounts.c >>> index ed9992f9..bfbe9042 100644 >>> --- a/src/vfs/idmapped-mounts.c >>> +++ b/src/vfs/idmapped-mounts.c >>> @@ -3838,8 +3838,6 @@ int tcore_setgid_create_idmapped(const struct vfstest_info *info) >>> goto out; >>> } >>> - supported = openat_tmpfile_supported(open_tree_fd); >>> - >>> pid = fork(); >>> if (pid < 0) { >>> log_stderr("failure: fork"); >>> @@ -3849,6 +3847,8 @@ int tcore_setgid_create_idmapped(const struct vfstest_info *info) >>> if (!switch_ids(10000, 11000)) >>> die("failure: switch fsids"); >>> + supported = openat_tmpfile_supported(open_tree_fd); >>> + >>> /* create regular file via open() */ >>> file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, S_IXGRP | S_ISGID); >>> if (file1_fd < 0) >>> @@ -4014,8 +4014,6 @@ int tcore_setgid_create_idmapped_in_userns(const struct vfstest_info *info) >>> goto out; >>> } >>> - supported = openat_tmpfile_supported(open_tree_fd); >>> - >>> pid = fork(); >>> if (pid < 0) { >>> log_stderr("failure: fork"); >>> @@ -4025,6 +4023,8 @@ int tcore_setgid_create_idmapped_in_userns(const struct vfstest_info *info) >>> if (!switch_userns(attr.userns_fd, 0, 0, false)) >>> die("failure: switch_userns"); >>> + supported = openat_tmpfile_supported(open_tree_fd); >>> + >>> /* create regular file via open() */ >>> file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, S_IXGRP | S_ISGID); >>> if (file1_fd < 0) >>> @@ -4133,6 +4133,8 @@ int tcore_setgid_create_idmapped_in_userns(const struct vfstest_info *info) >>> if (!switch_userns(attr.userns_fd, 0, 0, false)) >>> die("failure: switch_userns"); >>> + supported = openat_tmpfile_supported(open_tree_fd); >>> + >>> if (!caps_down_fsetid()) >>> die("failure: caps_down_fsetid"); >>> @@ -4257,6 +4259,8 @@ int tcore_setgid_create_idmapped_in_userns(const struct vfstest_info *info) >>> if (!switch_userns(attr.userns_fd, 0, 1000, false)) >>> die("failure: switch_userns"); >>> + supported = openat_tmpfile_supported(open_tree_fd); >>> + >>> if (!caps_down_fsetid()) >>> die("failure: caps_down_fsetid"); >>> @@ -7733,8 +7737,6 @@ static int setgid_create_umask_idmapped(const struct vfstest_info *info) >>> goto out; >>> } >>> - supported = openat_tmpfile_supported(open_tree_fd); >>> - >>> pid = fork(); >>> if (pid < 0) { >>> log_stderr("failure: fork"); >>> @@ -7752,6 +7754,8 @@ static int setgid_create_umask_idmapped(const struct vfstest_info *info) >>> if (!switch_ids(10000, 11000)) >>> die("failure: switch fsids"); >>> + supported = openat_tmpfile_supported(open_tree_fd); >>> + >>> /* create regular file via open() */ >>> file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, S_IXGRP | S_ISGID); >>> if (file1_fd < 0) >>> @@ -7947,8 +7951,6 @@ static int setgid_create_umask_idmapped_in_userns(const struct vfstest_info *inf >>> goto out; >>> } >>> - supported = openat_tmpfile_supported(open_tree_fd); >>> - >>> /* >>> * Below we verify that setgid inheritance for a newly created file or >>> * directory works correctly. As part of this we need to verify that >>> @@ -7984,6 +7986,8 @@ static int setgid_create_umask_idmapped_in_userns(const struct vfstest_info *inf >>> if (!switch_userns(attr.userns_fd, 0, 0, false)) >>> die("failure: switch_userns"); >>> + supported = openat_tmpfile_supported(open_tree_fd); >>> + >>> if (!caps_down_fsetid()) >>> die("failure: caps_down_fsetid"); >>> @@ -8181,8 +8185,6 @@ static int setgid_create_acl_idmapped(const struct vfstest_info *info) >>> goto out; >>> } >>> - supported = openat_tmpfile_supported(open_tree_fd); >>> - >>> pid = fork(); >>> if (pid < 0) { >>> log_stderr("failure: fork"); >>> @@ -8207,6 +8209,8 @@ static int setgid_create_acl_idmapped(const struct vfstest_info *info) >>> if (!switch_ids(10000, 11000)) >>> die("failure: switch fsids"); >>> + supported = openat_tmpfile_supported(open_tree_fd); >>> + >>> /* create regular file via open() */ >>> file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, S_IXGRP | S_ISGID); >>> if (file1_fd < 0) >>> @@ -8342,6 +8346,8 @@ static int setgid_create_acl_idmapped(const struct vfstest_info *info) >>> if (!switch_ids(10000, 11000)) >>> die("failure: switch fsids"); >>> + supported = openat_tmpfile_supported(open_tree_fd); >>> + >>> /* create regular file via open() */ >>> file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, S_IXGRP | S_ISGID); >>> if (file1_fd < 0) >>> @@ -8536,8 +8542,6 @@ static int setgid_create_acl_idmapped_in_userns(const struct vfstest_info *info) >>> goto out; >>> } >>> - supported = openat_tmpfile_supported(open_tree_fd); >>> - >>> /* >>> * Below we verify that setgid inheritance for a newly created file or >>> * directory works correctly. As part of this we need to verify that >>> @@ -8580,6 +8584,8 @@ static int setgid_create_acl_idmapped_in_userns(const struct vfstest_info *info) >>> if (!switch_userns(attr.userns_fd, 0, 0, false)) >>> die("failure: switch_userns"); >>> + supported = openat_tmpfile_supported(open_tree_fd); >>> + >>> if (!caps_down_fsetid()) >>> die("failure: caps_down_fsetid"); >>> @@ -8723,6 +8729,8 @@ static int setgid_create_acl_idmapped_in_userns(const struct vfstest_info *info) >>> if (!switch_userns(attr.userns_fd, 0, 0, false)) >>> die("failure: switch_userns"); >>> + supported = openat_tmpfile_supported(open_tree_fd); >>> + >>> if (!caps_down_fsetid()) >>> die("failure: caps_down_fsetid"); >> >