From 5756c96c9fb1b77503297460836081ad1487850b Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Thu, 10 Nov 2022 20:19:37 +0100 Subject: [PATCH] archiver: Fix race condition resulting in files containing null IDs In some rare cases files could be created which contain null IDs (all zero) in their content list. This was caused by a race condition between growing the `Content` slice and inserting the blob IDs into it. In some cases the blob ID was written to the old slice, which a short time afterwards was replaced with a larger copy, that did not yet contain the blob ID. --- internal/archiver/blob_saver_test.go | 5 +++++ internal/archiver/file_saver.go | 3 +++ 2 files changed, 8 insertions(+) diff --git a/internal/archiver/blob_saver_test.go b/internal/archiver/blob_saver_test.go index caa1e7c39..367b7be8b 100644 --- a/internal/archiver/blob_saver_test.go +++ b/internal/archiver/blob_saver_test.go @@ -48,14 +48,19 @@ func TestBlobSaver(t *testing.T) { var wait sync.WaitGroup var results []SaveBlobResponse + var lock sync.Mutex wait.Add(20) for i := 0; i < 20; i++ { buf := &Buffer{Data: []byte(fmt.Sprintf("foo%d", i))} idx := i + lock.Lock() results = append(results, SaveBlobResponse{}) + lock.Unlock() b.Save(ctx, restic.DataBlob, buf, func(res SaveBlobResponse) { + lock.Lock() results[idx] = res + lock.Unlock() wait.Done() }) } diff --git a/internal/archiver/file_saver.go b/internal/archiver/file_saver.go index 346bf736e..0742c8b57 100644 --- a/internal/archiver/file_saver.go +++ b/internal/archiver/file_saver.go @@ -199,7 +199,10 @@ func (s *FileSaver) saveFile(ctx context.Context, chnker *chunker.Chunker, snPat // add a place to store the saveBlob result pos := idx + + lock.Lock() node.Content = append(node.Content, restic.ID{}) + lock.Unlock() s.saveBlob(ctx, restic.DataBlob, buf, func(sbr SaveBlobResponse) { lock.Lock()