From 1dffebaf2abbb9628cc09b29ec0881738c3756cd Mon Sep 17 00:00:00 2001 From: Mateusz Urbanek Date: Thu, 30 Apr 2026 10:28:00 +0200 Subject: [PATCH] fix: mount throws EPERM on virtiofs with SELinux Fixes #13245 Signed-off-by: Mateusz Urbanek --- internal/pkg/mount/v3/point.go | 12 ++++++++++-- pkg/provision/providers/vm/virtiofsd.go | 10 ++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/internal/pkg/mount/v3/point.go b/internal/pkg/mount/v3/point.go index c020e646e..dc4560370 100644 --- a/internal/pkg/mount/v3/point.go +++ b/internal/pkg/mount/v3/point.go @@ -94,6 +94,8 @@ func (p *Point) Mount(opts Options) error { // FilterSelinuxLabelErrors filters out certain errors when setting the SELinux label on the mount point. // - ENOTSUP is ignored for all filesystems, as it indicates that the filesystem does not support extended attributes. // - EROFS is ignored for virtiofs, as it indicates that the underlying filesystem is read-only and does not support setting labels. +// - EPERM is ignored for virtiofs, as setting security.selinux xattrs may be blocked by the host or virtiofsd +// even though the mount is otherwise functional. func FilterSelinuxLabelErrors(target, fstype string, err error) error { if err == nil { return nil @@ -103,8 +105,14 @@ func FilterSelinuxLabelErrors(target, fstype string, err error) error { return nil } - if fstype == "virtiofs" && errors.Is(err, unix.EROFS) { - return nil + if fstype == "virtiofs" { + switch { + case errors.Is(err, unix.EROFS): + return nil + case errors.Is(err, unix.EPERM): + return nil + default: + } } return fmt.Errorf("error setting selinux label on %q: %w", target, err) diff --git a/pkg/provision/providers/vm/virtiofsd.go b/pkg/provision/providers/vm/virtiofsd.go index f95c07bfa..e5b7f9c28 100644 --- a/pkg/provision/providers/vm/virtiofsd.go +++ b/pkg/provision/providers/vm/virtiofsd.go @@ -27,6 +27,14 @@ func (p *Provisioner) FindVirtiofsd() (string, error) { return p.findVirtiofsd() } +// The first rule combines what could be separate client and server rules into +// a single all rule, matching 'security.' in either client arguments or lists +// returned from the host. This prevents the client from seeing and/or setting +// any 'security.' attributes on the server. +// +// More info: https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/doc/xattr-mapping.md +const xattrmap = `/bad/all/security./security.//ok/all///` + // Virtiofsd starts virtiofsd and restarts it if it exits. // The restart is needed, because the virtiofsd exits when client disconnects. func Virtiofsd(ctx context.Context, virtiofsdBin, share, socket string) error { @@ -43,6 +51,8 @@ func Virtiofsd(ctx context.Context, virtiofsdBin, share, socket string) error { "--socket-path", socket, "--announce-submounts", "--inode-file-handles=mandatory", + "--xattr", + "--xattrmap=" + xattrmap, } fmt.Printf("Starting virtiofsd with restart loop: %s %s\n",