Skip to content

Preserve POSIX ACLs when replacing archives - #561

Open
srkyn wants to merge 2 commits into
nih-at:mainfrom
srkyn:codex/preserve-posix-acl
Open

Preserve POSIX ACLs when replacing archives#561
srkyn wants to merge 2 commits into
nih-at:mainfrom
srkyn:codex/preserve-posix-acl

Conversation

@srkyn

@srkyn srkyn commented Aug 15, 2026

Copy link
Copy Markdown

When libzip replaces an existing archive, the replacement inode can lose an extended POSIX access ACL even though its mode bits are restored. Mode bits are not always an equivalent fallback: for an extended ACL, the group-class bits represent the ACL mask, so dropping the ACL can change which principals receive those permissions.

This revision is rebased onto the new temporary-file permission flow from 31eefd7. It fills the ACL-copy TODO in copy_permissions() and keeps the replacement at 0600 until commit-time permissions are applied.

The change:

  • uses Linux's dependency-free system.posix_acl_access xattr interface;
  • checks the getxattr() and setxattr() functions that are called and enables the code behind one USE_ACL guard;
  • adds no library or CI package dependency;
  • treats missing or unsupported ACL xattrs as having no ACL to copy, while failing before rename on real copy errors; and
  • restores the original mode after copying the ACL.

The regression creates an archive with a named-user access ACL and verifies preservation through both an ordinary archive update and a direct named-source replacement.

Validation:

  • ACL regression: passed.
  • xattr-disabled configuration and build: passed; the ACL target is omitted.
  • GCC full regression suite: 189/191 passed; the same two AES-backend fixture tests fail on an unmodified upstream control in this environment.
  • Clang ASan/UBSan ACL regression: passed.
  • clang-format --dry-run --Werror and git diff --check: passed.

@dillof

dillof commented Aug 19, 2026

Copy link
Copy Markdown
Member

Reading your changes lead us to redesign how permission copying is implemented: If we are going to replace an existing file, we create the temporary file with permissions 0600 and copy the permissions when replacing the file.

Could you please adapt your PR to that? There is a TODO comment where the ACL copy function should be called.

Also, don't restrict it to Linux, other system also implement this API. And check for the functions you call, not the existence of the header file. If you need to check for multiple functions, define a USE_ACL at the top of the file if all requirements are met, and use that throughout the rest of the file (to avoid duplicating the logic).

@dillof dillof added the feedback Waiting for feedback from submitter. label Aug 19, 2026
@srkyn srkyn closed this Aug 19, 2026
@srkyn
srkyn deleted the codex/preserve-posix-acl branch August 19, 2026 14:16
@srkyn
srkyn restored the codex/preserve-posix-acl branch August 19, 2026 14:17
@srkyn srkyn reopened this Aug 19, 2026
@srkyn
srkyn force-pushed the codex/preserve-posix-acl branch from 5ef3f43 to cae933b Compare August 19, 2026 14:28
@srkyn

srkyn commented Aug 19, 2026

Copy link
Copy Markdown
Author

Thanks. I rebased onto the new permission-copy flow and adapted the PR.

It now uses the portable acl_get_file() / acl_set_file() API, checks the functions it calls, and keeps the implementation behind a single USE_ACL guard. I also updated the regression to use the portable API and enabled libacl in Linux CI. The ACL-enabled, ACL-disabled, and ASan/UBSan checks all pass.

@dillof

dillof commented Aug 19, 2026

Copy link
Copy Markdown
Member

Thanks. However, since acl_get_file is in a separate library on Linux, and we would like to avoid extra dependencies for libzip, I would prefer if you reverted to the previous API.

@srkyn

srkyn commented Aug 19, 2026

Copy link
Copy Markdown
Author

Understood. I restored the dependency-free getxattr() / setxattr() implementation and kept it in the new copy_permissions() flow. The libacl detection, link, and CI package are gone. I also changed configuration to check the two functions directly and reran the ACL, disabled-feature, full, and sanitizer builds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feedback Waiting for feedback from submitter.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants