* [PATCH v2] 9pfs: local: read native symlinks when security-model=mapped
@ 2025-11-22 20:19 Andrey Erokhin
2025-11-25 14:04 ` Greg Kurz
2025-11-28 10:23 ` Christian Schoenebeck
0 siblings, 2 replies; 8+ messages in thread
From: Andrey Erokhin @ 2025-11-22 20:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Greg Kurz, Christian Schoenebeck
Directories attached using virtfs with security-model=mapped
may contain native symlinks
This can happen e.g. when booting from a rootfs directory tree
(usually with a writable overlay set up on the host side)
Currently, when security-model=mapped[-xattr|-file],
QEMU assumes that host-side "symlinks" are in the mapped format,
i.e. are regular files storing the linked path,
so it tries to open with O_NOFOLLOW
and fails with ELOOP on native symlinks
This patch introduces a fallback for such cases:
reuse security-model=[none|passthrough] else if branch logic
where readlink will be called for the path basename
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/173
Signed-off-by: Andrey Erokhin <language.lawyer@gmail.com>
---
hw/9pfs/9p-local.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 6230466de1..ddf111b674 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -474,12 +474,16 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
fd = local_open_nofollow(fs_ctx, fs_path->data, O_RDONLY, 0);
if (fd == -1) {
+ if (errno == ELOOP) {
+ goto native_symlink;
+ }
return -1;
}
tsize = RETRY_ON_EINTR(read(fd, (void *)buf, bufsz));
close_preserve_errno(fd);
} else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
(fs_ctx->export_flags & V9FS_SM_NONE)) {
+ native_symlink:;
char *dirpath = g_path_get_dirname(fs_path->data);
char *name = g_path_get_basename(fs_path->data);
int dirfd;
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] 9pfs: local: read native symlinks when security-model=mapped
2025-11-22 20:19 [PATCH v2] 9pfs: local: read native symlinks when security-model=mapped Andrey Erokhin
@ 2025-11-25 14:04 ` Greg Kurz
2025-11-25 14:21 ` Andrey Erokhin
2025-11-28 10:23 ` Christian Schoenebeck
1 sibling, 1 reply; 8+ messages in thread
From: Greg Kurz @ 2025-11-25 14:04 UTC (permalink / raw)
To: Andrey Erokhin; +Cc: qemu-devel, Christian Schoenebeck
On Sun, 23 Nov 2025 01:19:09 +0500
Andrey Erokhin <language.lawyer@gmail.com> wrote:
> Directories attached using virtfs with security-model=mapped
> may contain native symlinks
>
> This can happen e.g. when booting from a rootfs directory tree
> (usually with a writable overlay set up on the host side)
>
> Currently, when security-model=mapped[-xattr|-file],
> QEMU assumes that host-side "symlinks" are in the mapped format,
> i.e. are regular files storing the linked path,
This looks like an unfortunate design choice to start with. The mapped-xattr
mode was introduced to cache client-side uids/gids/mode in extended attributes.
Since there was no support in linux to set extended attributes on symlinks at
the time, 879c28133dfa ("virtio-9p: Security model for symlink and readlink")
opted to convert client originated symlinks into regular files.
A better choice would probably have been to leave symlinks as is and to cache
the metadata in a separate file, a bit like what the mapped-file does.
> so it tries to open with O_NOFOLLOW
> and fails with ELOOP on native symlinks
>
> This patch introduces a fallback for such cases:
> reuse security-model=[none|passthrough] else if branch logic
> where readlink will be called for the path basename
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/173
>
> Signed-off-by: Andrey Erokhin <language.lawyer@gmail.com>
> ---
> hw/9pfs/9p-local.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
> index 6230466de1..ddf111b674 100644
> --- a/hw/9pfs/9p-local.c
> +++ b/hw/9pfs/9p-local.c
> @@ -474,12 +474,16 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
>
> fd = local_open_nofollow(fs_ctx, fs_path->data, O_RDONLY, 0);
> if (fd == -1) {
> + if (errno == ELOOP) {
> + goto native_symlink;
> + }
> return -1;
> }
> tsize = RETRY_ON_EINTR(read(fd, (void *)buf, bufsz));
> close_preserve_errno(fd);
> } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
> (fs_ctx->export_flags & V9FS_SM_NONE)) {
> + native_symlink:;
Still has the terminating but unneeded semicolon. With that fixed,
Reviewed-by: Greg Kurz <groug@kaod.org>
> char *dirpath = g_path_get_dirname(fs_path->data);
> char *name = g_path_get_basename(fs_path->data);
> int dirfd;
--
Greg
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] 9pfs: local: read native symlinks when security-model=mapped
2025-11-25 14:04 ` Greg Kurz
@ 2025-11-25 14:21 ` Andrey Erokhin
2025-11-25 18:58 ` Greg Kurz
0 siblings, 1 reply; 8+ messages in thread
From: Andrey Erokhin @ 2025-11-25 14:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Christian Schoenebeck, Greg Kurz
>> + native_symlink:;
>
> Still has the terminating but unneeded semicolon
I think I've addressed this in the v1 thread, with links to the C11 draft grammar.
Can repeat in plain English: a label shall be followed by a statement. (No, declaration is not a statement)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] 9pfs: local: read native symlinks when security-model=mapped
2025-11-25 14:21 ` Andrey Erokhin
@ 2025-11-25 18:58 ` Greg Kurz
2025-11-25 19:31 ` Christian Schoenebeck
0 siblings, 1 reply; 8+ messages in thread
From: Greg Kurz @ 2025-11-25 18:58 UTC (permalink / raw)
To: Andrey Erokhin; +Cc: qemu-devel, Christian Schoenebeck
On Tue, 25 Nov 2025 19:21:00 +0500
Andrey Erokhin <language.lawyer@gmail.com> wrote:
> >> + native_symlink:;
> >
> > Still has the terminating but unneeded semicolon
>
> I think I've addressed this in the v1 thread, with links to the C11 draft grammar.
> Can repeat in plain English: a label shall be followed by a statement. (No, declaration is not a statement)
My bad, I didn't see your answer.
It is funny that I had to pass -pedantic to gcc to get a complaint (in plain
English as well) if I drop the semicolon :
warning: a label can only be part of a statement and a declaration is not a statement [-Wpedantic]
Cheers,
--
Greg
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] 9pfs: local: read native symlinks when security-model=mapped
2025-11-25 18:58 ` Greg Kurz
@ 2025-11-25 19:31 ` Christian Schoenebeck
2025-11-25 20:40 ` Andrey Erokhin
0 siblings, 1 reply; 8+ messages in thread
From: Christian Schoenebeck @ 2025-11-25 19:31 UTC (permalink / raw)
To: Andrey Erokhin, Greg Kurz; +Cc: qemu-devel
On Tuesday, 25 November 2025 19:58:19 CET Greg Kurz wrote:
> On Tue, 25 Nov 2025 19:21:00 +0500
>
> Andrey Erokhin <language.lawyer@gmail.com> wrote:
> > >> + native_symlink:;
> > >
> > > Still has the terminating but unneeded semicolon
> >
> > I think I've addressed this in the v1 thread, with links to the C11 draft
> > grammar. Can repeat in plain English: a label shall be followed by a
> > statement. (No, declaration is not a statement)
> My bad, I didn't see your answer.
>
> It is funny that I had to pass -pedantic to gcc to get a complaint (in plain
> English as well) if I drop the semicolon :
>
> warning: a label can only be part of a statement and a declaration is not a
> statement [-Wpedantic]
>
> Cheers,
Yes, I noticed that as well. GCC compiles fine without the semicolon, clang
OTOH errors:
../hw/9pfs/9p-local.c:481:9: error: expected expression
char *dirpath = g_path_get_dirname(fs_path->data);
^
Anyway, Andrey is right of course. The C standard defines a "labeled-
statement" as
identifier : statement
...
and the subsequent line in the patch is a declaration, not a statement.
But I also understand if GCC developers relaxed this rule. Because it "feels"
like both, a declaration and a statement. Interesting, because usually it's
clang to be more relaxed than GCC.
/Christian
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] 9pfs: local: read native symlinks when security-model=mapped
2025-11-25 19:31 ` Christian Schoenebeck
@ 2025-11-25 20:40 ` Andrey Erokhin
2025-11-26 12:26 ` Christian Schoenebeck
0 siblings, 1 reply; 8+ messages in thread
From: Andrey Erokhin @ 2025-11-25 20:40 UTC (permalink / raw)
To: Christian Schoenebeck, Greg Kurz; +Cc: qemu-devel
On 26/11/2025 00:31, Christian Schoenebeck wrote:
> On Tuesday, 25 November 2025 19:58:19 CET Greg Kurz wrote:
>> On Tue, 25 Nov 2025 19:21:00 +0500
>>
>> Andrey Erokhin <language.lawyer@gmail.com> wrote:
>>>>> + native_symlink:;
>>>>
>>>> Still has the terminating but unneeded semicolon
>>>
>>> I think I've addressed this in the v1 thread, with links to the C11 draft
>>> grammar. Can repeat in plain English: a label shall be followed by a
>>> statement. (No, declaration is not a statement)
>> My bad, I didn't see your answer.
>>
>> It is funny that I had to pass -pedantic to gcc to get a complaint (in plain
>> English as well) if I drop the semicolon :
>>
>> warning: a label can only be part of a statement and a declaration is not a
>> statement [-Wpedantic]
>>
>> Cheers,
>
> Yes, I noticed that as well. GCC compiles fine without the semicolon, clang
> OTOH errors:
>
> ../hw/9pfs/9p-local.c:481:9: error: expected expression
> char *dirpath = g_path_get_dirname(fs_path->data);
> ^
I use clangd language server, so I don't even need to compile, I see the error immediately in the editor ;)
> Anyway, Andrey is right of course. The C standard defines a "labeled-
> statement" as
>
> identifier : statement
> ...
>
> and the subsequent line in the patch is a declaration, not a statement.
>
> But I also understand if GCC developers relaxed this rule. Because it "feels"
> like both, a declaration and a statement. Interesting, because usually it's
> clang to be more relaxed than GCC.
Probably GCC allowed mixing declarations and statements in a block way before C99, in C++-like way, which has statement → declaration-statement → block-declaration production
(C99+ uses block-item → declaration|statement)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] 9pfs: local: read native symlinks when security-model=mapped
2025-11-25 20:40 ` Andrey Erokhin
@ 2025-11-26 12:26 ` Christian Schoenebeck
0 siblings, 0 replies; 8+ messages in thread
From: Christian Schoenebeck @ 2025-11-26 12:26 UTC (permalink / raw)
To: Greg Kurz, Andrey Erokhin; +Cc: qemu-devel
On Tuesday, 25 November 2025 21:40:57 CET Andrey Erokhin wrote:
> On 26/11/2025 00:31, Christian Schoenebeck wrote:
> > On Tuesday, 25 November 2025 19:58:19 CET Greg Kurz wrote:
[...]
> > Anyway, Andrey is right of course. The C standard defines a "labeled-
> > statement" as
> >
> > identifier : statement
> > ...
> >
> > and the subsequent line in the patch is a declaration, not a statement.
> >
> > But I also understand if GCC developers relaxed this rule. Because it
> > "feels" like both, a declaration and a statement. Interesting, because
> > usually it's clang to be more relaxed than GCC.
>
> Probably GCC allowed mixing declarations and statements in a block way
> before C99, in C++-like way, which has statement → declaration-statement →
> block-declaration production (C99+ uses block-item → declaration|statement)
It's not that old. It was introduced by the following commit in GCC, simply
because the C23 standard now allows labels to "appear before declarations and
at the end of compound statements.":
commit 8b7a9a249a63e066cff6e95db05a3158b4cc56cc
Author: Martin Uecker <muecker@gwdg.de>
Date: Sat Nov 7 00:48:33 2020 +0100
C Parser: Implement mixing of labels and code.
Implement mixing of labels and code as adopted for C2X
and process some std-attributes on labels.
[...]
And in fact, clang -std=c23 accepts it without error or warning as well.
/Christian
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] 9pfs: local: read native symlinks when security-model=mapped
2025-11-22 20:19 [PATCH v2] 9pfs: local: read native symlinks when security-model=mapped Andrey Erokhin
2025-11-25 14:04 ` Greg Kurz
@ 2025-11-28 10:23 ` Christian Schoenebeck
1 sibling, 0 replies; 8+ messages in thread
From: Christian Schoenebeck @ 2025-11-28 10:23 UTC (permalink / raw)
To: Greg Kurz, Andrey Erokhin; +Cc: qemu-devel
On Saturday, 22 November 2025 21:19:09 CET Andrey Erokhin wrote:
> Directories attached using virtfs with security-model=mapped
> may contain native symlinks
>
> This can happen e.g. when booting from a rootfs directory tree
> (usually with a writable overlay set up on the host side)
>
> Currently, when security-model=mapped[-xattr|-file],
> QEMU assumes that host-side "symlinks" are in the mapped format,
> i.e. are regular files storing the linked path,
> so it tries to open with O_NOFOLLOW
> and fails with ELOOP on native symlinks
>
> This patch introduces a fallback for such cases:
> reuse security-model=[none|passthrough] else if branch logic
> where readlink will be called for the path basename
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/173
>
> Signed-off-by: Andrey Erokhin <language.lawyer@gmail.com>
> ---
> hw/9pfs/9p-local.c | 4 ++++
> 1 file changed, 4 insertions(+)
Queued on 9p.next:
https://github.com/cschoenebeck/qemu/commits/9p.next
Thanks!
/Christian
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-11-28 10:24 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-22 20:19 [PATCH v2] 9pfs: local: read native symlinks when security-model=mapped Andrey Erokhin
2025-11-25 14:04 ` Greg Kurz
2025-11-25 14:21 ` Andrey Erokhin
2025-11-25 18:58 ` Greg Kurz
2025-11-25 19:31 ` Christian Schoenebeck
2025-11-25 20:40 ` Andrey Erokhin
2025-11-26 12:26 ` Christian Schoenebeck
2025-11-28 10:23 ` Christian Schoenebeck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).