Skip to content

fix: validate symlinks stay within source root when staging to S3 - #6570

Open
mufaddal-rohawala wants to merge 1 commit into
aws:masterfrom
mufaddal-rohawala:fix/model-trainer-source-dir-symlink-validation
Open

mufaddal-rohawala wants to merge 1 commit into
aws:masterfrom
mufaddal-rohawala:fix/model-trainer-source-dir-symlink-validation

Conversation

@mufaddal-rohawala

Copy link
Copy Markdown
Member

When ModelTrainer stages a local source_dir to S3 for the code channel, it copies/archives the directory (shutil.copytree, Session.upload_data), which follows nested symlinks: a symlink under source_dir that points elsewhere on the file system gets packaged as a regular file, pulling in unrelated content.

Validate source_dir before staging the code channel in _create_training_job_args, reusing _validate_source_directory and _validate_symlinks_within_root from sagemaker.core.common_utils (the same guards ModelBuilder uses, added in #6545). The check is scoped to source_dir and skipped for LOCAL_CONTAINER (which mounts via EFS and does not upload). User InputData data channels are intentionally not covered, so shared-storage and local Hugging Face snapshot layouts that rely on symlinks keep working, consistent with #6545. Nested symlinks that resolve inside source_dir (relative or absolute) are still supported; S3 and .tar.gz inputs are unaffected.

Adds unit tests driven through _create_training_job_args(): an in-root symlink is staged, an out-of-root symlink is rejected, and a data channel with an out-of-root symlink still uploads.

Behavior change: a symlink under source_dir that resolves outside source_dir now raises ValueError during ModelTrainer.train(). To fix, copy the target into source_dir or point source_dir at a parent directory that contains both.

Issue #, if available:

Description of changes:

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

When ModelTrainer stages a local source_dir to S3 for the code channel, it
copies/archives the directory (shutil.copytree, Session.upload_data), which
follows nested symlinks: a symlink under source_dir that points elsewhere on
the file system gets packaged as a regular file, pulling in unrelated content.

Validate source_dir before staging the code channel in _create_training_job_args,
reusing _validate_source_directory and _validate_symlinks_within_root from
sagemaker.core.common_utils (the same guards ModelBuilder uses, added in aws#6545).
The check is scoped to source_dir and skipped for LOCAL_CONTAINER (which mounts
via EFS and does not upload). User InputData data channels are intentionally not
covered, so shared-storage and local Hugging Face snapshot layouts that rely on
symlinks keep working, consistent with aws#6545. Nested symlinks that resolve inside
source_dir (relative or absolute) are still supported; S3 and .tar.gz inputs are
unaffected.

Adds unit tests driven through _create_training_job_args(): an in-root symlink is
staged, an out-of-root symlink is rejected, and a data channel with an out-of-root
symlink still uploads.

Behavior change: a symlink under source_dir that resolves outside source_dir now
raises ValueError during ModelTrainer.train(). To fix, copy the target into
source_dir or point source_dir at a parent directory that contains both.

This branch was successfully deployed

1 active deployment
auto-approve — 291abdb2 Deployed Nov 6, 2026 by mufaddal-rohawala via wait-for-approval #2187
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.

3 participants