Skip to content

archive: extract safe symlinks on old Python#2576

Merged
berendt merged 1 commit into
mainfrom
fix-archive-symlink-fallback
Jul 11, 2026
Merged

archive: extract safe symlinks on old Python#2576
berendt merged 1 commit into
mainfrom
fix-archive-symlink-fallback

Conversation

@ideaship

Copy link
Copy Markdown
Contributor

Problem

The daily release-tox-drift job (periodic-daily pipeline) has been failing since the release repo was added as a fetched source. It crashes during source fetching, not on detected drift:

source error: unsafe archive member (link/special): osism-release-a2e4875/1.0.0/ceph.yml
drift: exit 2 ... evaluation failed :(

_safe_extract downloads each source repo as a GitHub tarball and extracts it. When tarfile.data_filter is available (Python 3.11.4+ / 3.12+) it extracts with filter="data", which permits relative symlinks that stay inside the extraction directory. The manual fallback for older Pythons rejected every symlink member outright — stricter than the data filter it was meant to emulate.

The Zuul node runs Python 3.11.2, which predates the data_filter backport, so it takes the fallback path. The release repo contains ~80 legitimate relative symlinks (per-version ceph.yml / openstack.yml aliases), so extraction aborted on the first one. Local runs and release-tox-drift-test never caught this because their interpreters have data_filter.

Fix

Make the fallback emulate the data filter: permit symlinks/hardlinks whose target resolves inside the extraction root, keep rejecting links that escape (absolute or via ..) and any other special member. The final extractall is made version-robust (filter="fully_trusted" where supported, plain extractall otherwise) so it behaves identically on old and new interpreters.

Verification

  • New regression test reproduces the exact CI error, then passes with the fix; the existing absolute-symlink rejection test is retained.
  • Full suite: 332 passed. flake8 + black clean.
  • End-to-end: forcing the no-data_filter path and extracting an archive built from the real release tree now succeeds (6 symlinks resolved) where it previously raised.

🤖 Generated with Claude Code

The daily release-tox-drift job crashed while fetching sources with:

  source error: unsafe archive member (link/special):
  osism-release-a2e4875/1.0.0/ceph.yml

_safe_extract downloads each source repo as a GitHub tarball and
extracts it. When tarfile.data_filter is available (Python 3.11.4+ /
3.12+) it extracts with filter="data", which permits relative symlinks
that stay inside the extraction directory. The manual fallback for
older Pythons, however, rejected every symlink member outright, so it
was stricter than the data filter it was meant to emulate.

The Zuul node runs Python 3.11.2, which predates the data_filter
backport, so it takes the fallback path. The release repo -- now one of
the fetched sources -- contains ~80 legitimate relative symlinks
(per-version ceph.yml and openstack.yml aliases), so extraction aborted
on the first one and the whole check exited non-zero. Local runs and the
release-tox-drift-test job never caught this because their interpreters
have data_filter.

Make the fallback emulate the data filter: permit symlinks and
hardlinks whose target resolves inside the extraction root, and keep
rejecting links that escape (absolute or via ..) and any other special
member. The final extractall is made version-robust
(filter="fully_trusted" where supported, plain extractall otherwise) so
it behaves identically on old and new interpreters.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Roger Luethi <luethi@osism.tech>
@ideaship ideaship marked this pull request as ready for review July 10, 2026 17:51
@ideaship ideaship requested a review from berendt July 10, 2026 17:51
@ideaship ideaship moved this from New to In review in Human Board Jul 10, 2026
@berendt berendt merged commit 3a269db into main Jul 11, 2026
3 checks passed
@berendt berendt deleted the fix-archive-symlink-fallback branch July 11, 2026 20:09
@github-project-automation github-project-automation Bot moved this from In review to Done in Human Board Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants