Skip to content

fix(file-manager): backport symlink-safe rsync targets to 7.3 - #2746

Merged
tom mortensen (limetech) merged 5 commits into
7.3from
fix/os-871-rsync-target-path-7-3
Sep 16, 2026
Merged

tom mortensen (limetech) merged 5 commits into
7.3from
fix/os-871-rsync-target-path-7-3

Conversation

@SimonFair

@SimonFair SimonFair commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Summary

This backport brings the File Manager rsync symlink hardening from OS-871 to the 7.3 release branch. It rejects arbitrary symlink components and translates only verified Unraid exclusive-share mappings.

Why This Exists

Rsync 3.5.0 rejects untrusted symlink components in operator-supplied paths. The previous implementation used recursive realpath() resolution, which could hide an attacker-controlled symlink from rsync before its security checks ran. This backport is tracked by OS-872, with the original behavior tracked by OS-871.

Resolution

Walk the destination path component by component with lstat(). Translate only the OS-managed /mnt/user/<share> or /mnt/user0/<share> exclusive-share link after verifying the share state, exact backing target, system.LOCATION, and configured storage. Reject every other symlink component and preserve missing descendants and trailing slashes.

Reviewer Considerations

  • This branch contains the same security change as PR fix(file-manager): resolve symlink-backed rsync targets #2745, applied to 7.3.
  • The compatibility exception is limited to the known exclusive-share root; arbitrary user-created links are rejected before rsync receives a pre-resolved path.
  • Copy and move operations use the same target adapter; source handling and copy/delete behavior are unchanged.
  • --insecure-links is not used.
  • A live Unraid test is still needed to confirm the exact exclusive-share metadata on the target release.

Behavior Changes

File Manager operations into arbitrary symlink-backed destinations now fail closed. Verified exclusive-share destinations continue to use their physical backing path for rsync.

Implementation Summary

  • Replace recursive realpath() target resolution with a component walk.
  • Validate and translate only verified exclusive-share links.
  • Reject unrecognized symlink destinations.
  • Apply the adapter to both copy and move operations.
  • Update regression coverage for symlink rejection and call-site wiring.

Verification

  • php -l emhttp/plugins/dynamix/nchan/file_manager
  • php -l tests/file-manager-rsync-target-path.php
  • php tests/file-manager-rsync-target-path.php
  • git diff --check

Validation Limits

The local regression test uses a temporary symlink fixture. Full validation of the exclusive-share exception requires an Unraid runtime with state/shares.ini, state/disks.ini, and system.LOCATION metadata.

Risk

Contained; the change fails closed for unknown symlinks and does not disable rsync security checks. The main compatibility risk is intentionally stricter handling of non-system symlink destinations.

Resolve symlink-backed destinations before File Manager rsync operations so rsync 3.5.0 does not reject exclusive-share paths. Preserve the existing path boundary and rsync security checks.\n\nLinear: OS-871
@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 5dd2c7e4-56bb-44c1-88ad-bd6aedf1340a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

🔧 PR Test Plugin Available

A test plugin has been generated for this PR that includes the modified files.

Version: 2026.09.09.1249
Build: View Workflow Run

📥 Installation Instructions:

Install via Unraid Web UI:

  1. Go to Plugins → Install Plugin
  2. Copy and paste this URL:
https://preview.dl.unraid.net/pr-plugins/pr-2746/webgui-pr-2746.plg
  1. Click Install

Alternative: Direct Download

⚠️ Important Notes:

  • Testing only: This plugin is for testing PR changes
  • Backup included: Original files are automatically backed up
  • Easy removal: Files are restored when plugin is removed
  • Conflicts: Remove this plugin before installing production updates
  • Post-merge behavior: This preview stays available after merge until preview storage expires or it is manually cleaned up

📝 Modified Files:

Click to expand file list
emhttp/plugins/dynamix/nchan/file_manager

🔄 To Remove:

Navigate to Plugins → Installed Plugins and remove webgui-pr-2746, or run:

plugin remove webgui-pr-2746

🤖 This comment is automatically generated and will be updated with each new push to this PR.

Cover the rsync target adapter and both copy and move call sites. Clean up temporary fixtures when setup fails and document the new helpers.\n\nLinear: OS-871\nReview: #2745
@SimonFair
SimonFair marked this pull request as ready for review September 8, 2026 19:20
@unraid-bot Unraid Bot (unraid-bot) added QA Passed QA passed (auto-managed by notification-worker) 7.4.0 Approved for release 7.4.0 (auto-managed by notification-worker) and removed 7.4.0 Approved for release 7.4.0 (auto-managed by notification-worker) labels Sep 9, 2026
Limit exclusive-share path translation to verified OS mappings and reject other symlink components before rsync receives a pre-resolved path. This preserves rsync 3.5 symlink protections while retaining exclusive-share support.

Linear: OS-872

Backport of OS-871
Use getfattr --no-dereference so the exclusive-share validation reads the OS-managed symlink attribute instead of following it to the backing directory.
@unraid-bot Unraid Bot (unraid-bot) added 7.4.0 Approved for release 7.4.0 (auto-managed by notification-worker) 7.3.3 Approved for release 7.3.3 (auto-managed by notification-worker) and removed 7.4.0 Approved for release 7.4.0 (auto-managed by notification-worker) labels Sep 15, 2026
@limetech
tom mortensen (limetech) merged commit 41e8d5a into 7.3 Sep 16, 2026
5 checks passed
@limetech
tom mortensen (limetech) deleted the fix/os-871-rsync-target-path-7-3 branch September 16, 2026 16:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

7.3.3 Approved for release 7.3.3 (auto-managed by notification-worker) QA Passed QA passed (auto-managed by notification-worker)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants