Skip to content

docs(metadata): audit --fake-super / --super privilege paths#3435

Merged
oferchen merged 1 commit into
masterfrom
docs/fake-super-privilege-audit-v2
Apr 29, 2026
Merged

docs(metadata): audit --fake-super / --super privilege paths#3435
oferchen merged 1 commit into
masterfrom
docs/fake-super-privilege-audit-v2

Conversation

@oferchen
Copy link
Copy Markdown
Owner

Summary

Adds docs/audits/fake-super-privilege.md, a structured audit of the --fake-super, --super, and --copy-as code paths against upstream rsync 3.4.1.

The audit identifies 10 findings (3 HIGH, 5 MEDIUM, 2 LOW) where the current implementation diverges from upstream semantics or is incompletely wired:

  • HIGHload_fake_super is exported but never called from any production path; special-file executors invoke real syscalls without the upstream am_root < 0 placeholder substitution; daemon parses fake super = yes but no read site demotes am_root or rewrites --super.
  • MEDIUM — missing -XX / repeated-flag validation; chmod path doesn't honour fake-super and touch-up-dirs is missing; am_root() is binary instead of upstream tri-state; remote invocation builder unconditionally pushes --fake-super; --copy-as is parsed but never calls setuid/setgid.
  • LOWFakeSuperStat::encode skips to_wire_mode; rdev (0,0) is decoded to None and lost on round-trip.

Each finding includes Evidence (file:line citations into both this codebase and target/interop/upstream-src/rsync-3.4.1/), Impact, and a Recommended fix. The audit closes with a 10-item follow-up task table referencing the upstream sources.

This is documentation only — no behavioural change.

Refs: #1839

Test plan

  • Documentation only; no code changes
  • Spot-checked F1-F3 against the current Rust code paths
  • Cited upstream xattrs.c:340-720, syscall.c:90-174, clientserver.c:1080-1107, rsync.c:do_as_root

Audit of oc-rsync's `--fake-super`, `--super`, and `--copy-as`
implementations against upstream rsync 3.4.1. Identifies 3 HIGH, 5
MEDIUM, and 2 LOW findings, all with file:line evidence and upstream
cross-references. Top issues: `load_fake_super` is exported but never
called (F1), special-file executors invoke real `mknod` syscalls under
fake-super (F2), and the daemon parses `fake super = yes` but no read
site actually demotes `am_root` (F3). Audit document only; ten
follow-up issues recommended for the actual fixes.

Closes #1839.
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Apr 29, 2026
@oferchen oferchen merged commit 75f9ac2 into master Apr 29, 2026
12 checks passed
@oferchen oferchen deleted the docs/fake-super-privilege-audit-v2 branch April 29, 2026 10:21
oferchen added a commit that referenced this pull request May 1, 2026
…3435)

Audit of oc-rsync's `--fake-super`, `--super`, and `--copy-as`
implementations against upstream rsync 3.4.1. Identifies 3 HIGH, 5
MEDIUM, and 2 LOW findings, all with file:line evidence and upstream
cross-references. Top issues: `load_fake_super` is exported but never
called (F1), special-file executors invoke real `mknod` syscalls under
fake-super (F2), and the daemon parses `fake super = yes` but no read
site actually demotes `am_root` (F3). Audit document only; ten
follow-up issues recommended for the actual fixes.

Closes #1839.
oferchen added a commit that referenced this pull request May 1, 2026
Implements F1 and F2 from docs/audits/fake-super-privilege.md (#3435):

- F1: load_fake_super was exported but never called. Add a fast-path
  read in apply_ownership_via_fake_super so a re-application skips the
  rewrite when the existing rsync.%stat xattr already matches the
  desired stat. Mirrors xattrs.c:read_stat_xattr() / set_file_attrs().
- F2: copy_device and copy_fifo invoked mknod(2) unconditionally,
  failing without CAP_MKNOD under --fake-super. Add
  create_{fifo,device_node}_with_fake_super wrappers in metadata::special
  which substitute a regular 0600 placeholder when fake-super is active,
  mirroring upstream syscall.c:do_mknod()'s am_root < 0 branch. After
  placeholder creation, the local-copy executors store the would-be
  mode/uid/gid/rdev in the rsync.%stat xattr so the destination can be
  faithfully restored on a later --fake-super pull.

Also fixes a latent S_IFMT loss in apply_ownership_via_fake_super:
entry.permissions() drops the file-type bits, but xattrs.c:set_stat_xattr
encodes the full mode. Use entry.mode() instead.

Tests:
- 3 unit tests in metadata::special covering fake-super placeholder
  substitution for FIFO and device, and the disabled fall-through.
- 3 integration tests in metadata::apply::tests covering the wire-side
  receiver path: xattr is written, chown is not invoked, and an
  identical second application is a no-op.

All new code is gated by #[cfg(unix)] / #[cfg(all(unix, feature =
"xattr"))]. Non-Unix targets continue to fall through to the existing
no-op stubs. No unsafe code is introduced; metadata is on the
permitted-unsafe list but this change uses only safe std/rustix APIs.
oferchen added a commit that referenced this pull request May 5, 2026
…3435)

Audit of oc-rsync's `--fake-super`, `--super`, and `--copy-as`
implementations against upstream rsync 3.4.1. Identifies 3 HIGH, 5
MEDIUM, and 2 LOW findings, all with file:line evidence and upstream
cross-references. Top issues: `load_fake_super` is exported but never
called (F1), special-file executors invoke real `mknod` syscalls under
fake-super (F2), and the daemon parses `fake super = yes` but no read
site actually demotes `am_root` (F3). Audit document only; ten
follow-up issues recommended for the actual fixes.

Closes #1839.
oferchen added a commit that referenced this pull request May 5, 2026
Implements F1 and F2 from docs/audits/fake-super-privilege.md (#3435):

- F1: load_fake_super was exported but never called. Add a fast-path
  read in apply_ownership_via_fake_super so a re-application skips the
  rewrite when the existing rsync.%stat xattr already matches the
  desired stat. Mirrors xattrs.c:read_stat_xattr() / set_file_attrs().
- F2: copy_device and copy_fifo invoked mknod(2) unconditionally,
  failing without CAP_MKNOD under --fake-super. Add
  create_{fifo,device_node}_with_fake_super wrappers in metadata::special
  which substitute a regular 0600 placeholder when fake-super is active,
  mirroring upstream syscall.c:do_mknod()'s am_root < 0 branch. After
  placeholder creation, the local-copy executors store the would-be
  mode/uid/gid/rdev in the rsync.%stat xattr so the destination can be
  faithfully restored on a later --fake-super pull.

Also fixes a latent S_IFMT loss in apply_ownership_via_fake_super:
entry.permissions() drops the file-type bits, but xattrs.c:set_stat_xattr
encodes the full mode. Use entry.mode() instead.

Tests:
- 3 unit tests in metadata::special covering fake-super placeholder
  substitution for FIFO and device, and the disabled fall-through.
- 3 integration tests in metadata::apply::tests covering the wire-side
  receiver path: xattr is written, chown is not invoked, and an
  identical second application is a no-op.

All new code is gated by #[cfg(unix)] / #[cfg(all(unix, feature =
"xattr"))]. Non-Unix targets continue to fall through to the existing
no-op stubs. No unsafe code is introduced; metadata is on the
permitted-unsafe list but this change uses only safe std/rustix APIs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant