Browse Source

internal/repository: Fix LoadBlob + fuzz test

When given a buf that is big enough for a compressed blob but not its
decompressed contents, the copy at the end of LoadBlob would skip the
last part of the contents.

Fixes #3783.
master
greatroar 6 months ago
parent
commit
c9557b2822
  1. 2
      .gitattributes
  2. 43
      internal/repository/fuzz_test.go
  3. 3
      internal/repository/repository.go
  4. 3
      internal/repository/testdata/fuzz/FuzzSaveLoadBlob/62d79435b9ad1777d0562c405e1ab2e1ef5d11d07c8aa4fe6814010294bffd33

2
.gitattributes vendored

@ -0,0 +1,2 @@
# Workaround for https://github.com/golang/go/issues/52268.
**/testdata/fuzz/*/* eol=lf

43
internal/repository/fuzz_test.go

@ -0,0 +1,43 @@
//go:build go1.18
// +build go1.18
package repository
import (
"context"
"testing"
"github.com/restic/restic/internal/backend/mem"
"github.com/restic/restic/internal/restic"
)
// Test saving a blob and loading it again, with varying buffer sizes.
// Also a regression test for #3783.
func FuzzSaveLoadBlob(f *testing.F) {
f.Fuzz(func(t *testing.T, blob []byte, buflen uint) {
if buflen > 64<<20 {
// Don't allocate enormous buffers. We're not testing the allocator.
t.Skip()
}
id := restic.Hash(blob)
repo, _ := TestRepositoryWithBackend(t, mem.New(), 2)
_, _, err := repo.SaveBlob(context.TODO(), restic.DataBlob, blob, id, false)
if err != nil {
t.Fatal(err)
}
err = repo.Flush(context.TODO())
if err != nil {
t.Fatal(err)
}
buf, err := repo.LoadBlob(context.TODO(), restic.DataBlob, id, make([]byte, buflen))
if err != nil {
t.Fatal(err)
}
if restic.Hash(buf) != id {
t.Fatal("mismatch")
}
})
}

3
internal/repository/repository.go

@ -303,8 +303,9 @@ func (r *Repository) LoadBlob(ctx context.Context, t restic.BlobType, id restic.
return plaintext, nil
}
// move decrypted data to the start of the buffer
buf = buf[:len(plaintext)]
copy(buf, plaintext)
return buf[:len(plaintext)], nil
return buf, nil
}
if lastError != nil {

3
internal/repository/testdata/fuzz/FuzzSaveLoadBlob/62d79435b9ad1777d0562c405e1ab2e1ef5d11d07c8aa4fe6814010294bffd33 vendored

@ -0,0 +1,3 @@
go test fuzz v1
[]byte("\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6")
uint(109)
Loading…
Cancel
Save