3 Commits

Author SHA1 Message Date
Tonis Tiigi
4dcf35c691 executor/oci: pin resolved WCOW cache source
Resolve the selected cache subpath through the same handle used to
pin it, then verify that resolved target is still within the cache
root before passing it as the mount source.

This closes the check-to-use gap where containment verification and
pinning could observe different path objects. It also avoids handing
HCS the original path containing attacker-controlled reparse points.

Open the pinned directory with delete access while omitting delete
sharing, so the selected resolved directory cannot be renamed, deleted,
or swapped before HCS consumes the mount source. Keep write sharing
enabled so writable cache contents can still be modified while the
handle is alive.

Keep the HCS-facing source in the normal DOS path form when possible,
so this does not introduce a new \\?\ path format requirement for WCOW
mount realization.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit d854e00d473958b6e164f2e821eab902245705ad)
(cherry picked from commit 44c0ed6b1c)
2026-07-16 17:37:16 -07:00
Dawei Wei
2ee0a47757 executor/oci: pin WCOW cache mount source across mount realization
The Windows cache mount is realized later by HCS from the resolved host
path, so verification alone leaves a check-to-use window in which the
verified entry could be swapped for a junction escaping the cache root
(concurrent cache access). Hold the verified source open with
GENERIC_READ and a share mode that omits FILE_SHARE_DELETE until the
mount is released, so the entry cannot be renamed or deleted (and thus
swapped) during that window. GENERIC_READ rather than DELETE is used so a
concurrent read/traverse open by the mount stack still succeeds;
validated against a real HCS worker (benign cache mounts still mount and
the escape is still rejected).

Add a unit test asserting the source cannot be renamed while pinned and
can be renamed after release.

Signed-off-by: Dawei Wei <wei.dawei.cn@gmail.com>
(cherry picked from commit 39a7b40489a036134a93502ea3d84d71dca072ea)
(cherry picked from commit 473663bad0)
2026-07-16 17:37:11 -07:00
Dawei Wei
0c3bb3c7ed executor/oci: confine WCOW cache mount source within cache root
On Windows, RUN --mount=type=cache,source=<subdir> resolved the source
subpath with fs.RootPath, which does not follow Windows reparse points.
A junction placed inside the cache root could therefore point to a path
outside the cache, and the resolved source was mounted into the build
container, exposing host files outside the intended cache subdirectory.

Resolve the real path of both the cache root and the selected source via
GetFinalPathNameByHandle (which follows junctions and symlinks) and reject
any source that resolves outside the cache root.

Add Windows unit tests for the resolver and end-to-end regression tests
for the junction escape (Windows) and the symlink escape (Linux).

Signed-off-by: Dawei Wei <wei.dawei.cn@gmail.com>
(cherry picked from commit 70370e18de3cc7545fcf7f986612a28a803f59d2)
(cherry picked from commit a9155a456b)
2026-07-16 17:37:06 -07:00