apple / apple/container

[Bug]: openat(O_CREAT) on bind mount fails when file mode lacks owner-read bit

Open
#1,344 2 comments 2 reactions 0 assignees View on GitHub
virtualization-support-needed
Dominant language
Swift
Stars
49.9k
Forks
1.8k
Avg merge
1d 20h
Merged PRs (30d)
22

Description

### I have done the following

- [x] I have searched the existing issues
- [ ] If possible, I've reproduced the issue using the 'main' branch of this project

### Steps to reproduce

When a non-root process creates a file on a bind-mounted host directory, `openat(O_WRONLY|O_CREAT, mode)` returns `EACCES` if the mode lacks the owner-read bit (`0400`). The same call succeeds on the container's native filesystem.

## Reproducer

```bash
mkdir /tmp/virtiofs-repro

container run --rm --user 1000:1000 -v /tmp/virtiofs-repro:/mnt alpine sh -c '
apk add --no-cache python3 > /dev/null 2>&1
mkdir /mnt/test

python3 -c "
import os
d = \"/mnt/test\"

# Works: mode includes owner-read
fd = os.open(d + \"/ok\", os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
os.close(fd)
print(\"mode 0600 (rw-------): OK\")

# Fails: mode lacks owner-read
try:
fd = os.open(d + \"/fail\", os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o200)
os.close(fd)
print(\"mode 0200 (-w-------): OK\")
except PermissionError:
print(\"mode 0200 (-w-------): FAILED\")

# Control: same call on native filesystem works
os.makedirs(\"/tmp/native\", exist_ok=True)
fd = os.open(\"/tmp/native/ok\", os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o200)
os.close(fd)
print(\"mode 0200 on native fs: OK\")
"'

rm -rf /tmp/virtiofs-repro
```

## Impact

This breaks C++ `std::filesystem::copy`, which internally creates destination files with `openat(O_WRONLY|O_CREAT|O_TRUNC, 0200)`. In my case, [Nix](https://nixos.org/) package manager builds fail because of this.

The key line in GCC's libstdc++ is here: https://github.com/gcc-mirror/gcc/blob/4eef89cc39a629988453e964258374cd7a047b1f/libstdc%2B%2B-v3/src/filesystem/ops-common.h#L553

## Related issues

- [containers/podman#24725](https://github.com/containers/podman/issues/24725) — same underlying virtiofs bug, reported as `mkdirat(., ., 0)` failing with EACCES on vfkit macOS. References Apple feedback ticket **FB16008360**.
- [docker/for-mac#6812](https://github.com/docker/for-mac/issues/6812) — virtiofs maps file permissions incorrectly on macOS
- [crc-org/vfkit#70](https://github.com/crc-org/vfkit/issues/70) — APFS-backed virtiofs permission issues

### Current behavior

```
mode 0600 (rw-------): OK
mode 0200 (-w-------): FAILED
mode 0200 on native fs: OK
```

### Expected behavior

```
Mode 0600 (rw-------): OK
mode 0200 (-w-------): OK
mode 0200 on native fs: OK
```

### Environment

```markdown
- OS: macOS 26.3.1 (a) (25D771280a)
- Xcode:
- Container: 0.10.0
```

### Relevant log output

```shell
N/A
```

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct

Contributor guide

Open the contributing guide

Research direction

Start by running the provided container and Python reproducer on macOS, then search the repository for the openat, O_CREAT, and virtiofs handling involved in bind-mounted files. Compare the bind-mounted and native-filesystem results; done means mode 0200 creation succeeds for a non-root process and the relevant tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, macos, python, swift
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.