apple / apple/containerization

[Bug]: archive ownership changes clear set-ID permission bits

Open Beginner friendly
#819 1 comment 1 reaction 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.