fix: mount throws EPERM on virtiofs with SELinux

Fixes #13245

Signed-off-by: Mateusz Urbanek <mateusz.urbanek@siderolabs.com>
This commit is contained in:
Mateusz Urbanek 2026-04-30 10:28:00 +02:00
parent 48a481c29f
commit 1dffebaf2a
No known key found for this signature in database
GPG Key ID: F16F84591E26D77F
2 changed files with 20 additions and 2 deletions

View File

@ -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)

View File

@ -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",