Skip to content

directory resolver ignores --exclude for symlink targets - #5253

Open
goingforstudying-ctrl wants to merge 1 commit into
anchore:mainfrom
goingforstudying-ctrl:fix-exclude-symlink-targets
Open

directory resolver ignores --exclude for symlink targets#5253
goingforstudying-ctrl wants to merge 1 commit into
anchore:mainfrom
goingforstudying-ctrl:fix-exclude-symlink-targets

Conversation

@goingforstudying-ctrl

Copy link
Copy Markdown

Description

Ran into this while digging through the exclusion code after #5232 popped up: --exclude only ever matches the excluded directory entry itself. That's fine for the primary walk (hitting the entry returns SkipDir), but the directory indexer follows symlinks by resolving the target and queueing it as a second index root. That second pass starts at the target file, the excluded directory entry is never visited, and the exclusion never fires.

So with --exclude ./boot and a symlink like etc/grub2.cfg -> ../boot/grub2/grub.cfg, everything under /boot still ends up indexed and cataloged. Reproduced it with the fixture from the issue: 745 npm packages cataloged from a yarn.lock that lives in the excluded tree, purely through the symlink.

The fix does two things:

  • symlink entries get their real path resolved and checked against the exclusions, so a link pointing into an excluded tree is skipped before its target ever becomes an index root
  • literal (non-glob) exclusion patterns now also match by directory prefix, so descendants reached through routes other than the primary walk are covered too

Glob patterns keep the same doublestar behavior as before, just applied to both the visited path and the resolved path. Dangling links behave the same as today (resolve to nothing, nothing gets indexed).

Verified end to end on the fixture: before, syft scan dir:. --exclude ./boot cataloged 745 npm artifacts through the symlink; after, the same command catalogs 0.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I have added unit tests that cover changed behavior
  • I have tested my code in common scenarios and confirmed there are no regressions
  • I have added comments to my code, particularly in hard-to-understand sections

Issue references

Fixes #5232

the exclusion visitor only ever matched the excluded directory entry
itself, which works for the primary walk because hitting that entry
returns SkipDir. but the indexer follows symlinks by resolving the
target and queueing it as an additional index root, and that second
pass starts at the target file without ever visiting the excluded
directory entry, so the exclusion never fires. the net effect was that
--exclude ./boot still indexed and cataloged everything under /boot
reachable through an unexcluded symlink.

fix it two ways: resolve the real path for symlink entries and apply
the exclusions to it, and treat literal exclusion patterns as directory
prefixes so descendants match too. glob patterns keep their existing
doublestar behavior on both the visited and the resolved path.

Signed-off-by: goingforstudying-ctrl <goingforstudying@gmail.com>
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.

--exclude is not honored for paths reached via a symlink target

1 participant