Skip to content

fix(SFTP): infinite loop scanning directories with upward symlinks #52289

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

leftybournes
Copy link

@leftybournes leftybournes commented Apr 22, 2025

Summary

When a symlink is detected, check if the path already includes the file. If it does, ignore the file. This helps prevents the scanner from going into an infinite loop when the configured root contains a directory symlinked to a parent/grandparent/higher directory which eventually contains it.

Checklist

@leftybournes leftybournes requested a review from a team as a code owner April 22, 2025 07:40
@leftybournes leftybournes requested review from artonge, nfebe and skjnldsv and removed request for a team April 22, 2025 07:40
@sorbaugh sorbaugh requested review from artonge, icewind1991 and Altahrim and removed request for artonge April 22, 2025 07:56
Copy link
Member

@provokateurin provokateurin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some tests for this would be great :)

$fileAdded = false;

if (!empty($linkedPath)) {
$fileAdded = substr_count($absPath, basename($absPath) . '/' . $file) > 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using substr_count is quite unsafe here.
It does not check that the linked path really is part of the parent path.
It can also lead to other funny problems when there are files and folders with similar names and your check would confuse a symlink at /dir123/sym to a file at /dir to cause the loop with /dir123 while it actually doesn't.

Besides that I'm not sure what you are checking here, since you are not involving the $linkedPath and it seems to me like this will always evaluate to true (but I might be wrong as I don't know how this exactly works).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm comparing the symlink along with each child (e.g. sym/child_dir) done in basename($absPath) . '/' . $file against the current absolute path and it only checks if the current path is a symlink. Would the issue persist in that case?

From my testing, $linkedPath is a blank string when it's checked against a regular file or directory so checking if it's not empty evaluates to false in those cases as expected.

I see that my code lacks clarity. I'll make adjustments accordingly.

@leftybournes
Copy link
Author

Some tests for this would be great :)

Sure, I'll add tests for this.

The absolute path currently always starts with a '/' so check the
current directory along with each symlinked child if it is already in
the path (e.g. /parent/symlink/). Adding '/' to both ends helps with
avoiding collisions with partial matches in the path.

Signed-off-by: Kent Delante <[email protected]>
@leftybournes leftybournes force-pushed the leftybournes/fix/sftp_scan_infinite_loop branch from 21b37b2 to f9cfd2c Compare April 25, 2025 08:56
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]: files_external SFTP can loop infinitely on symlink and fill databases and prevent cron to finish
2 participants