diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index b2bc247f924..fa9be241c2e 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -512,9 +512,13 @@ func ImportChain(ctx context.Context, r repo.Repo, fname string, snapshot bool) if err != nil { return xerrors.Errorf("fetching chain CAR failed: setting up resumable reader: %w", err) } + defer rrd.Close() //nolint:errcheck - rd = rrd l = rrd.ContentLength() + // without limiting the reader to exactly what we expect, an overread could + // result in a virtually freeform remote-error which we would then be unable + // to handle properly on our end + rd = io.LimitReader(rrd, l) } else { fname, err = homedir.Expand(fname) if err != nil { diff --git a/lib/httpreader/resumable.go b/lib/httpreader/resumable.go index dacefeccc9a..a638026bc61 100644 --- a/lib/httpreader/resumable.go +++ b/lib/httpreader/resumable.go @@ -24,6 +24,8 @@ type ResumableReader struct { reader io.ReadCloser } +var _ io.ReadCloser = (*ResumableReader)(nil) + func NewResumableReader(ctx context.Context, url string) (*ResumableReader, error) { finalURL := "" @@ -77,6 +79,13 @@ func (r *ResumableReader) ContentLength() int64 { return r.contentLength } +func (r *ResumableReader) Close() error { + if r.reader != nil { + return r.reader.Close() + } + return nil +} + func (r *ResumableReader) Read(p []byte) (n int, err error) { for { if r.reader == nil {