apple / apple/containerization
[Bug]: archive ownership changes clear set-ID permission bits
- Dominant language
- Swift
- Stars
- 8.9k
- Forks
- 359
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 13
Description
## I have done the following
- [x] I have searched the existing issues
- [x] I confirmed the ordering defect in `apple/containerization` `main` at `50f77222964ed3d01dcb53f803ea2d511656a9dc`
## Steps to reproduce
The syscall behaviour can be reproduced independently of the archive reader:
1. Create and open a regular file.
2. Call `fchmod(fd, 0o6755)`.
3. Call `fchown(fd, getuid(), getgid())`.
4. Call `fstat` and inspect `st_mode & 0o7777`.
On Darwin, step 3 clears the set-user-ID and set-group-ID bits, so the resulting mode is `0755`.
The same ordering exists in `ArchiveReader.setFileAttributes`: it calls `fchmod` before `fchown`. Once the full permission mask from #818 is restored, this archive-specific regression demonstrates the defect:
1. Write a regular archive entry with mode `06755`, owner `getuid()`, and group `getgid()`.
2. Extract it with `ArchiveReader`.
3. Read the extracted file's `.posixPermissions`.
4. Run:
```sh
swift test --disable-automatic-resolution -Xswiftc -warnings-as-errors --filter preserveSpecialPermissionBits
```
The test fails with:
```text
Expectation failed: ((setIDPerms & permMask) -> 493) == (0o6755 -> 3565)
Set-ID permission bits should be preserved after ownership
```
## Current behavior
`ArchiveReader.setFileAttributes` applies the archived mode and then changes ownership. Darwin's `fchown` clears set-user-ID and set-group-ID bits, including when ownership is set to the current UID and GID.
The issue is currently masked earlier by #818 because current `main` also truncates archive permissions to `0o777`. It remains an independent defect in the stock `main` syscall ordering and becomes observable as soon as the full permission mask is restored.
## Expected behavior
Archive extraction should set ownership first and apply the archived `0o7777` permission mode last, so the final extracted mode matches the archive entry.
## Environment
- OS: macOS 26.5.1 (25F80)
- Xcode: 26.6 (17F113)
- Swift: Apple Swift 6.3.3
- Containerization source: `apple/containerization` `main` at `50f77222964ed3d01dcb53f803ea2d511656a9dc`
## Relevant log output
```text
Test preserveSpecialPermissionBits() recorded an issue at ArchiveReaderTests.swift:484:9
Expectation failed: ((setIDPerms & permMask) -> 493) == (0o6755 -> 3565)
Set-ID permission bits should be preserved after ownership
Test run with 1 test in 1 suite failed with 1 issue.
```
## Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Contributor guide
Research direction
Start in ArchiveReader.setFileAttributes and inspect ArchiveReaderTests.swift around the preserveSpecialPermissionBits test. Run the provided swift test command to reproduce the failure, then verify extraction of a 06755 regular archive entry preserves its set-ID bits after ownership is applied.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100