Skip to content

fix(archive): restore permissions after ownership - #821

Open
stephenlclarke wants to merge 2 commits into
apple:mainfrom
stephenlclarke:fix/archive-permissions-after-ownership
Open

fix(archive): restore permissions after ownership#821
stephenlclarke wants to merge 2 commits into
apple:mainfrom
stephenlclarke:fix/archive-permissions-after-ownership

Conversation

@stephenlclarke

@stephenlclarke stephenlclarke commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Apply archived permissions after ownership so Darwin does not clear set-user-ID and set-group-ID bits during extraction.

Motivation and Context

During testing of my container-compose plugin, I found and fixed the following issue: ArchiveReader.setFileAttributes called fchmod before fchown. On Darwin, changing ownership clears set-user-ID and set-group-ID bits, so the final extracted mode does not match the archive entry.

Fixes #819.

Dependency and Merge Order

This PR targets the stock apple/containerization:main branch and depends on #820, which fixes #818. Please merge #820 first.

The head currently contains the signed #818 fix as its first prerequisite commit because both PRs target stock Apple main. After the prerequisite merges, the branch can merge current Apple main so this PR's remaining diff is only the ownership/permission ordering change and set-ID regression.

Reproduction

The syscall behaviour is directly reproducible:

  1. Create and open a regular file.
  2. Call fchmod(fd, 0o6755).
  3. Call fchown(fd, getuid(), getgid()).
  4. Inspect fstat(fd).st_mode & 0o7777.

Darwin reports 0755.

With the #818 mask fix present, the archive regression writes a regular entry with mode 06755, extracts it, and runs:

swift test --disable-automatic-resolution -Xswiftc -warnings-as-errors --filter preserveSpecialPermissionBits

Before reordering the calls, it failed with:

Expectation failed: ((setIDPerms & permMask) -> 493) == (0o6755 -> 3565)
Set-ID permission bits should be preserved after ownership

Changes

  • Call fchown before the final fchmod.
  • Extend the archive regression with a regular 06755 entry whose owner and group are explicitly restored.

Validation

Validated on macOS 26.5.1 (25F80), Xcode 26.6 (17F113), and Swift 6.3.3.

  • Regression before fix: failed with 0755 instead of 06755
  • Regression after fix: passed
  • make fmt: passed
  • make check: passed
  • swift test --enable-code-coverage --disable-automatic-resolution -Xswiftc -warnings-as-errors: 574 tests in 80 suites passed
  • git diff --check: passed
  • Commits 6e32963617b3ed8f4b63432dbcf834f94807342b and 726e1ffdceada5cc62d32c8fc939aef30220e6ff are cryptographically signed and verified

Compatibility and Risk

The change only alters the order of two existing file-descriptor operations. Ownership is still applied when both owner and group are present, and the archived mode becomes the final mode. There are no archive-format or public-API changes.

Related

Release Note Highlight

Archive extraction now preserves set-user-ID and set-group-ID bits when restoring file ownership.

Archive extraction masked modes to ordinary rwx bits, stripping sticky, set-user-ID, and set-group-ID permissions. Preserve the full POSIX permission mask and add a sticky-directory regression.
Darwin clears set-user-ID and set-group-ID bits when fchown changes ownership. Apply ownership first, then restore the archived mode, and extend the archive regression to cover set-ID permissions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

1 participant