Description
Environment
- macOS: Apple Silicon (arm64)
- Lima: via Colima
- VM type:
vz (Apple Virtualization.framework)
- Mount type:
virtiofs
- Guest: Debian (dev container), kernel 6.8.0-100-generic aarch64
- Mount:
lima-* on /workspaces type virtiofs (rw,relatime)
Description
open(path, O_CREAT|O_EXCL|O_RDONLY, 0000) on a virtiofs-mounted volume creates the file on the host but returns EACCES. The file is then completely inaccessible — cannot be stat'd, opened, or unlinked, even as root.
This affects any program that uses open(O_CREAT|O_EXCL, 0) for lock files (e.g., Go's os.OpenFile(path, os.O_CREATE|os.O_EXCL, 0)).
Reproduction
// mklock.c
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv) {
int fd = open(argv[1], O_CREAT | O_EXCL | O_RDONLY, 0000);
if (fd < 0) { perror("open"); return 1; }
close(fd);
printf("created: %s\n", argv[1]);
return 0;
}
cc mklock.c -o mklock
# On virtiofs mount — fails but creates the file:
./mklock /workspaces/test.lock
# open: Permission denied (errno=13)
# File exists as orphan:
ls -la /workspaces/ | grep test.lock
# ----------? 1 vscode vscode 0 ... test.lock
# Cannot stat, open, or remove — even as root:
sudo stat /workspaces/test.lock # Permission denied
sudo rm /workspaces/test.lock # Permission denied
# Same operation on native fs works correctly:
./mklock /tmp/test.lock # created: /tmp/test.lock
rm /tmp/test.lock # succeeds (after confirmation)
Expected behavior (POSIX)
open(O_CREAT|O_EXCL, 0000) should either:
- Succeed — return a valid fd (permission bits apply to subsequent opens, not the creating open), OR
- Fail atomically — return error without creating the file
unlink() should depend on parent directory permissions, not the file's own mode bits.
Root cause hypothesis
Apple's virtiofs implementation appears to:
- Create the file on the host with mode
0000
- Perform a post-creation access check against the file's permissions
- Fail the access check → return EACCES
- Not roll back the creation
This makes O_CREAT|O_EXCL non-atomic on virtiofs.
Additional note
Two-step creation works fine — install -m 000 /dev/null file (creates with 0644 then fchmod to 000) succeeds and the file can be subsequently removed. The bug is specific to atomically creating with mode 0000.
Description
Environment
vz(Apple Virtualization.framework)virtiofslima-* on /workspaces type virtiofs (rw,relatime)Description
open(path, O_CREAT|O_EXCL|O_RDONLY, 0000)on a virtiofs-mounted volume creates the file on the host but returnsEACCES. The file is then completely inaccessible — cannot be stat'd, opened, or unlinked, even as root.This affects any program that uses
open(O_CREAT|O_EXCL, 0)for lock files (e.g., Go'sos.OpenFile(path, os.O_CREATE|os.O_EXCL, 0)).Reproduction
Expected behavior (POSIX)
open(O_CREAT|O_EXCL, 0000)should either:unlink()should depend on parent directory permissions, not the file's own mode bits.Root cause hypothesis
Apple's virtiofs implementation appears to:
0000This makes
O_CREAT|O_EXCLnon-atomic on virtiofs.Additional note
Two-step creation works fine —
install -m 000 /dev/null file(creates with 0644 then fchmod to 000) succeeds and the file can be subsequently removed. The bug is specific to atomically creating with mode0000.