Skip to content

Commit

Permalink
copy: prevent potential deadlock if close before fully written
Browse files Browse the repository at this point in the history
We also need an additional check to avoid setting both the error and
response which can create a race where they can arrive in the receiving
thread in either order.

If we hit an error, we don't need to send the response.

> There is a condition where the registry (unexpectedly, not to spec)
> returns 201 or 204 on the put before the body is fully written. I would
> expect that the http library would issue close and could fall into a
> deadlock here. We could just read respC and call setResponse. In that
> case ErrClosedPipe would get returned and Commit shouldn't be called
> anyway.

Signed-off-by: Justin Chadwell <me@jedevc.com>
  • Loading branch information
jedevc committed Mar 4, 2024
1 parent 8727463 commit 52a1402
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions remotes/docker/pusher.go
Expand Up @@ -301,6 +301,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
err := remoteserrors.NewUnexpectedStatusErr(resp)
log.G(ctx).WithField("resp", resp).WithField("body", string(err.(remoteserrors.ErrUnexpectedStatus).Body)).Debug("unexpected response")
pushw.setError(err)
return
}
pushw.setResponse(resp)
}()
Expand Down Expand Up @@ -436,6 +437,8 @@ func (pw *pushWriter) Write(p []byte) (n int, err error) {
pw.Close()
case p := <-pw.pipeC:
return 0, pw.replacePipe(p)
case resp := <-pw.respC:
pw.setResponse(resp)
}
}
status.Offset += int64(n)
Expand Down

0 comments on commit 52a1402

Please sign in to comment.