Skip to content

fix: use lstat() in CreateTarget to prevent symlink traversal outside sandbox_root#29645

Open
Ashutosh0x wants to merge 1 commit into
bazelbuild:masterfrom
Ashutosh0x:security/no-symlink-follow-sandbox-root
Open

fix: use lstat() in CreateTarget to prevent symlink traversal outside sandbox_root#29645
Ashutosh0x wants to merge 1 commit into
bazelbuild:masterfrom
Ashutosh0x:security/no-symlink-follow-sandbox-root

Conversation

@Ashutosh0x
Copy link
Copy Markdown
Contributor

Fixes #28515

Summary

CreateTarget() in linux-sandbox-pid1.cc uses stat() to check whether a path already exists before creating mount targets under sandbox_root. Since stat() follows symlinks, a pre-seeded symlink under sandbox_root causes subsequent mkdir()/link() calls to operate on the host filesystem outside sandbox_root.

This is a robustness/hardening issue: hermetic sandbox setup code runs before pivot_root/chroot and performs host filesystem operations. If sandbox_root/<component> is unexpectedly a symlink, mount target creation can write outside the intended sandbox directory.

Root Cause

// BEFORE (vulnerable): stat() follows symlinks
if (stat(path, &sb) == 0) {
    // sb reflects the TARGET of any symlink, not the symlink itself
    // mkdir/link will operate at the symlink target (outside sandbox_root)
}

Fix

Two changes to CreateTarget():

  1. Replaced stat() with lstat() -- lstat() does not follow symlinks, so it reports the symlink itself rather than its target.

  2. Added explicit symlink rejection -- if lstat() detects a symlink (S_ISLNK), CreateTarget() now returns -1 with errno = ELOOP, preventing any further operations on the path.

// AFTER (safe): lstat() does not follow symlinks
if (lstat(path, &sb) == 0) {
    if (S_ISLNK(sb.st_mode)) {
        // Reject symlinks: following them could escape the sandbox root.
        errno = ELOOP;
        return -1;
    }
    // ... normal directory/file handling
}

Reproduction (from #28515)

proof_root="$(mktemp -d)"
sandbox_root="$proof_root/sandbox"
outside_root="$proof_root/outside"
mkdir -p "$sandbox_root"
ln -s "$outside_root" "$sandbox_root/mnt"
# Run linux-sandbox with hermetic mode -- CreateTarget will follow the symlink
# Before fix: "$outside_root/<something>" gets created on the host
# After fix: CreateTarget returns ELOOP, mount setup fails safely

Related

/cc @meisterT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR is awaiting review from an assigned reviewer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

hermetic linux-sandbox: mount target creation can follow pre-seeded symlinks under sandbox_root and create host paths outside sandbox_root

1 participant