Skip to content

fix tarsplit file leak #2323

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 7, 2025

Conversation

giuseppe
Copy link
Member

follow-up for #2312

@giuseppe giuseppe force-pushed the fix-leak-tarsplit branch from 577cdc5 to 3cf1a04 Compare April 29, 2025 20:18
@giuseppe giuseppe marked this pull request as ready for review April 30, 2025 16:44
Copy link
Collaborator

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

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

I think this fixes the part where closing chunkedDiffer closes / deletes the temporary file, by “stealing” the file handle. That’s fine.

But the current rules as documented in PrepareStagedLayer are that the caller only should only call CleanupStagedLayer if ApplyStagedLayer is not called / does not succeed; so, closing the file only in Cleanup… looks wrong. (Arguably the API is inconvenient, and should be changed in a way that callers always call “cleanup”, even on success of ApplyStagedLayer.)

@giuseppe giuseppe force-pushed the fix-leak-tarsplit branch from 3cf1a04 to 5408ffe Compare April 30, 2025 18:16
Copy link
Collaborator

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

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

Thanks!

Code LGTM, feel free to merge after comment updates.

store.go Outdated
@@ -365,6 +365,8 @@ type Store interface {
// PrepareStagedLayer applies a diff to a layer.
// It is the caller responsibility to clean the staging directory if it is not
// successfully applied with ApplyStagedLayer.
// The caller must ensure ApplyStagedLayer or CleanupStagedLayer is called eventually with
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: we can start using references to other functions/methods, i.e.

Suggested change
// The caller must ensure ApplyStagedLayer or CleanupStagedLayer is called eventually with
// The caller must ensure [Store.ApplyStagedLayer] or [Store.CleanupStagedLayer] is called eventually with

Copy link
Member Author

Choose a reason for hiding this comment

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

thanks, I've fixed only this instance for now and the new comments I've added

@giuseppe giuseppe force-pushed the fix-leak-tarsplit branch from 5408ffe to e6746b8 Compare May 7, 2025 06:51
giuseppe added 7 commits May 7, 2025 08:52
The ApplyDiffWithDiffer function was marked as deprecated,
with PrepareStagedLayer being the recommended replacement.
Its implementation was just a wrapper around PrepareStagedLayer.

Remove the deprecated function from the Store and LayerStore
interfaces and its implementation.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This change makes the final `nil` error return explicit, making the
successful exit path clearer.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Transfer ownership of the `tocDigest` file handle upon
successful completion of `ApplyDiff` in the chunked
differ.  This prevents the handle from being closed by
the differ if the operation succeeds, as ownership is
effectively passed along.

Explicitly close the `TarSplit` reader during
`CleanupStagedLayer` and `ApplyDiffWithDiffer`.  This ensures
the associated file handle is released even if the layer
application process is aborted or fails before the reader
is naturally consumed and closed elsewhere.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Ensure temporary file descriptors for tar-split data
are closed properly in error paths within zstd:chunked
handling.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
The chunkedDiffer object holds state and resources that are managed
within a single ApplyDiff call.  Reusing the same differ instance for
multiple ApplyDiff calls could lead to incorrect state or errors related
to already-closed resources.

Add a flag and check to ensure ApplyDiff cannot be called more than
once on the same chunkedDiffer instance, making its usage pattern explicit
and preventing potential misuse.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
it is an explicit API breaking change, so that cannot be used by old
users (e.g. an older containers/image version) that are not ported to
support the new semantic that only one ApplyDiffWithDiffer call is
supported for one differ object.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
The comment for the `TarSplit` field in `DriverWithDifferOutput`
was updated to make its ownership and the responsibility for
closing the file descriptor explicit.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Copy link
Collaborator

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

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

/lgtm

Thanks!

Copy link
Contributor

openshift-ci bot commented May 7, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: giuseppe, mtrmac

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot bot merged commit 36d562d into containers:main May 7, 2025
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants