Skip to content

bug: Push leaks ReadCloser from PullBlob on both success and error paths #491

@aftersnow

Description

@aftersnow

Description

In pkg/backend/push.go:175-189, src.PullBlob() returns an io.ReadCloser that is never explicitly closed — on both success and error paths.

The reader is wrapped with io.NopCloser(reader) before passing to dst.Blobs().Push(), so even when push closes the wrapper, the original content ReadCloser is not closed.

Code

content, err := src.PullBlob(ctx, repo, desc.Digest.String())
if err \!= nil {
    return err  // content not closed
}

reader := pb.Add(prompt, desc.Digest.String(), desc.Size, content)
// io.NopCloser means dst closing the wrapper does NOT close content
if err := dst.Blobs().Push(ctx, desc, io.NopCloser(reader)); err \!= nil {
    pb.Abort(desc.Digest.String(), err)
    return err  // content not closed
}
// success path: content also not closed

Fix

Add defer content.Close() immediately after the nil-error check.

Severity

Critical — resource leak under normal operation, not just error paths.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions