Skip to content

tar: Preserve trailing record-padding bytes after end-of-archive #292

Merged
jeckersb merged 3 commits intocomposefs:mainfrom
cgwalters:pax-padding-fix
May 7, 2026
Merged

tar: Preserve trailing record-padding bytes after end-of-archive #292
jeckersb merged 3 commits intocomposefs:mainfrom
cgwalters:pax-padding-fix

Conversation

@cgwalters
Copy link
Copy Markdown
Collaborator

Closes: #290

cgwalters added 3 commits May 7, 2026 14:20
The mirror-fixture-images.yml workflow only runs on pushes to main, so
during the PR that adds a new entry to ci/fixture-images.txt the
ghcr.io mirror does not yet exist.  Without a fallback, the integration
test would fail trying to pull from ghcr.io.

Add an upstream_ref field to ContainerImage and teach pull_image() to
try the mirror first, then warn and retry against the upstream registry
if the mirror pull fails.  Fill in upstream_ref for existing images
(UBI10 and centos-bootc) so the struct is complete.

Assisted-by: OpenCode (Claude Sonnet 4.6)
Signed-off-by: Colin Walters <walters@verbum.org>
GNU tar pads archives to a "record size" (typically 20 × 512 = 10240
bytes). The archive ends with two 512-byte zero blocks that tar-core
emits as ParseEvent::End, but any additional zero-padding blocks that
fill out the record were silently dropped.

split_async() stored only what ParseEvent::End::consumed covered (1024
bytes for the two zero blocks), leaving the remaining trailing bytes
unread. When cat() later reconstructed the archive, the output was
shorter than the original, causing the sha256 to differ from the
layer's diff_id. This broke the checksum validation path in
create_filesystem() — specifically the @digest reference path that
lacks a verity proof and must re-hash the reconstructed tar.

The fix reads any remaining bytes after the End event until true EOF
and stores them inline, making cat() byte-for-bit faithful to the
original archive. This resolves "Layer has incorrect checksum" errors
for images where the tar ends with GNU-style record padding, including
Ubuntu 26.04 (resolute) which uses umoci/PAX format.

Assisted-by: OpenCode (Claude Sonnet 4.6)
Signed-off-by: Colin Walters <walters@verbum.org>
Ubuntu 26.04 uses umoci/PAX format tars produced by Rockcraft, which
include GNU-style record padding after the end-of-archive blocks.
Before the preceding fix, this caused 'Layer has incorrect checksum'
errors on the @digest compute-id path because the reconstructed tar
was shorter than the original.

Pin the image by manifest digest (d31acef2) and record the expected
composefs image ID so regressions are caught automatically.

Assisted-by: OpenCode (Claude Sonnet 4.6)
Signed-off-by: Colin Walters <walters@verbum.org>
@cgwalters cgwalters requested a review from jeckersb May 7, 2026 19:19
Copy link
Copy Markdown
Collaborator

@jeckersb jeckersb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice!

@jeckersb jeckersb added this pull request to the merge queue May 7, 2026
Merged via the queue into composefs:main with commit 5d5e76e May 7, 2026
18 checks passed
@jmarrero
Copy link
Copy Markdown

jmarrero commented May 7, 2026

thanks @cgwalters for the quick fix.

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.

Layer has incorrect checksum with Ubuntu 26.04 (resolute) base image -- PAX tar format not round-tripped

3 participants