From 951b4a426bbd55b47af4bc3cac28ecddd262fb25 Mon Sep 17 00:00:00 2001 From: Juan Antonio Osorio Date: Thu, 12 Mar 2026 11:31:04 +0200 Subject: [PATCH] devices/fs: fix FUSE_ALLOW_IDMAP regression on Linux 6.12+ kernels Linux 6.12 added a check in fs/fuse/inode.c:process_init_reply that requires FUSE_POSIX_ACL to be present whenever FUSE_ALLOW_IDMAP is advertised. Without it, the kernel sets conn_error = 1, silently degrading the virtiofs connection. In this degraded state, reading and modifying existing files still works, but creating new files or directories fails with EPERM. This breaks any setup where the host user's GID doesn't match the guest user's GID (e.g., host 1000:1001 vs guest 1000:1000), because the idmapped mount that would translate GIDs never gets established. The root cause was that ALLOW_IDMAP was advertised from the server-global "supported" flags in server.rs, which meant it got enabled regardless of whether the backend could actually fulfill the POSIX_ACL contract that the kernel now requires alongside it. The fix moves ALLOW_IDMAP out of the server-global supported mask and into each passthrough backend's init() return value, coupled with POSIX_ACL. Now the negotiation looks like this: 1. If the kernel is capable of POSIX_ACL and the backend has xattr support enabled, advertise POSIX_ACL. 2. Only then, if the kernel is also capable of ALLOW_IDMAP, advertise ALLOW_IDMAP alongside it. This works for passthrough filesystems because the POSIX_ACL contract (mode-ACL synchronization, default ACL inheritance, ACL xattr storage) is fulfilled by the host kernel. The passthrough already forwards all xattr operations, including system.posix_acl_access and system.posix_acl_default, directly to the host via libc calls with no namespace filtering. Note that on kernels 6.2+, the FUSE VFS layer has fuse_get_acl() and fuse_set_acl() inode operations that handle idmapped UID/GID translation within ACL entries, so the passthrough server doesn't need to interpret ACL binary data itself. Both the Linux and macOS passthrough backends are updated with the same logic so we don't regress macOS-hosted Linux guests. Fixes: containers/libkrun#568 Signed-off-by: Juan Antonio Osorio --- src/devices/src/virtio/fs/linux/passthrough.rs | 12 ++++++++++++ src/devices/src/virtio/fs/macos/passthrough.rs | 12 ++++++++++++ src/devices/src/virtio/fs/server.rs | 3 +-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/devices/src/virtio/fs/linux/passthrough.rs b/src/devices/src/virtio/fs/linux/passthrough.rs index 79a2e1285..b6ed2c66d 100644 --- a/src/devices/src/virtio/fs/linux/passthrough.rs +++ b/src/devices/src/virtio/fs/linux/passthrough.rs @@ -990,6 +990,18 @@ impl FileSystem for PassthroughFs { self.announce_submounts.store(true, Ordering::Relaxed); } + // Enable POSIX ACL support when the kernel is capable and xattrs are enabled. + // For a passthrough filesystem, the host kernel handles ACL semantics — + // we just forward the system.posix_acl_* xattrs. + // ALLOW_IDMAP requires POSIX_ACL on Linux 6.12+ (see containers/libkrun#568). + if self.cfg.xattr && capable.contains(FsOptions::POSIX_ACL) { + opts |= FsOptions::POSIX_ACL; + + if capable.contains(FsOptions::ALLOW_IDMAP) { + opts |= FsOptions::ALLOW_IDMAP; + } + } + Ok(opts) } diff --git a/src/devices/src/virtio/fs/macos/passthrough.rs b/src/devices/src/virtio/fs/macos/passthrough.rs index f1b712bee..de83fde43 100644 --- a/src/devices/src/virtio/fs/macos/passthrough.rs +++ b/src/devices/src/virtio/fs/macos/passthrough.rs @@ -1174,6 +1174,18 @@ impl FileSystem for PassthroughFs { self.announce_submounts.store(true, Ordering::Relaxed); } + // Enable POSIX ACL support when the kernel is capable and xattrs are enabled. + // For a passthrough filesystem, the host kernel handles ACL semantics — + // we just forward the system.posix_acl_* xattrs. + // ALLOW_IDMAP requires POSIX_ACL on Linux 6.12+ (see containers/libkrun#568). + if self.cfg.xattr && capable.contains(FsOptions::POSIX_ACL) { + opts |= FsOptions::POSIX_ACL; + + if capable.contains(FsOptions::ALLOW_IDMAP) { + opts |= FsOptions::ALLOW_IDMAP; + } + } + Ok(opts) } diff --git a/src/devices/src/virtio/fs/server.rs b/src/devices/src/virtio/fs/server.rs index a6b436a35..a98264a62 100644 --- a/src/devices/src/virtio/fs/server.rs +++ b/src/devices/src/virtio/fs/server.rs @@ -895,8 +895,7 @@ impl Server { | FsOptions::MAX_PAGES | FsOptions::SUBMOUNTS | FsOptions::HANDLE_KILLPRIV_V2 - | FsOptions::INIT_EXT - | FsOptions::ALLOW_IDMAP; + | FsOptions::INIT_EXT; if cfg!(target_os = "macos") { supported |= FsOptions::SECURITY_CTX;