encrypt: fix race condition

1 view
Skip to first unread message

nor...@perkeep.org

unread,
Jun 21, 2022, 2:24:21 PM6/21/22
to camlistor...@googlegroups.com


https://github.com/perkeep/perkeep/commit/5069d49bbc2f5263f843ebb85dcea140ffc988d1

commit 5069d49bbc2f5263f843ebb85dcea140ffc988d1
Author: Michael Hoffmann <mho...@posteo.de>
Date: Mon Jun 20 18:04:40 2022 +0200

encrypt: fix race condition

diff --git a/pkg/blobserver/encrypt/encrypt.go b/pkg/blobserver/encrypt/encrypt.go
index 90d8fb2..cda425d 100644
--- a/pkg/blobserver/encrypt/encrypt.go
+++ b/pkg/blobserver/encrypt/encrypt.go
@@ -231,9 +231,8 @@ func (s *storage) Fetch(ctx context.Context, plainBR blob.Ref) (io.ReadCloser, u
return nil, 0, blobserver.ErrCorruptBlob
}

- plainBytes := pools.BytesBuffer()
- defer pools.PutBuffer(plainBytes)
-
+ // Using the pool here would be racy since the caller will read this asynchronously
+ plainBytes := bytes.NewBuffer(nil)
if err := s.decryptBlob(plainBytes, encBytes); err != nil {
return nil, 0, fmt.Errorf("encrypt: encrypted blob %s failed validation: %s", encBR, err)
}
diff --git a/pkg/blobserver/encrypt/encrypt_test.go b/pkg/blobserver/encrypt/encrypt_test.go
index 0c69765..fbc502f 100644
--- a/pkg/blobserver/encrypt/encrypt_test.go
+++ b/pkg/blobserver/encrypt/encrypt_test.go
@@ -33,6 +33,7 @@ import (
"os"
"runtime"
"strings"
+ "sync"
"testing"

"filippo.io/age"
@@ -166,6 +167,39 @@ func TestEncrypt(t *testing.T) {
}
}

+func TestEncryptStress(t *testing.T) {
+ const (
+ workers = 20
+ numBlobs = 1000
+ )
+
+ ts := newTestStorage()
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ blobs := make(chan string, workers)
+ defer close(blobs)
+
+ for i := 0; i < workers; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for blob := range blobs {
+ tb := &test.Blob{Contents: blob}
+ tb.MustUpload(t, ts.sto)
+ if got := ts.fetchOrErrorString(tb.BlobRef()); got != blob {
+ t.Errorf("Fetching plaintext blobref %v = %v; want %q", tb.BlobRef(), got, blob)
+ }
+ }
+ }()
+ }
+
+ for i := 0; i < numBlobs; i++ {
+ blobs <- fmt.Sprintf("%d", i)
+ }
+}
+
func TestLoadMeta(t *testing.T) {
ts := newTestStorage()
const blobData = "foo"
Reply all
Reply to author
Forward
0 new messages