Skip to content

Commit

Permalink
Prevent raft transactions from containing overlarge keys. (#13286) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ncabatoff authored Nov 26, 2021
1 parent 845ddcd commit cb06696
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
3 changes: 3 additions & 0 deletions changelog/13286.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
storage/raft: Fix a panic when trying to store a key > 32KB in a transaction.
```
3 changes: 3 additions & 0 deletions physical/raft/raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,9 @@ func (b *RaftBackend) Transaction(ctx context.Context, txns []*physical.TxnEntry
op := &LogOperation{}
switch txn.Operation {
case physical.PutOperation:
if len(txn.Entry.Key) > bolt.MaxKeySize {
return fmt.Errorf("%s, max key size for integrated storage is %d", physical.ErrKeyTooLarge, bolt.MaxKeySize)
}
op.OpType = putOp
op.Key = txn.Entry.Key
op.Value = txn.Entry.Value
Expand Down
39 changes: 39 additions & 0 deletions physical/raft/raft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,45 @@ func TestRaft_Backend_LargeValue(t *testing.T) {
}
}

func TestRaft_TransactionalBackend_LargeKey(t *testing.T) {
b, dir := getRaft(t, true, true)
defer os.RemoveAll(dir)

value := make([]byte, defaultMaxEntrySize+1)
rand.Read(value)

key, err := base62.Random(bolt.MaxKeySize + 1)
if err != nil {
t.Fatal(err)
}
txns := []*physical.TxnEntry{
{
Operation: physical.PutOperation,
Entry: &physical.Entry{
Key: key,
Value: []byte(key),
},
},
}

err = b.Transaction(context.Background(), txns)
if err == nil {
t.Fatal("expected error for transactions")
}

if !strings.Contains(err.Error(), physical.ErrKeyTooLarge) {
t.Fatalf("expected %q, got %v", physical.ErrValueTooLarge, err)
}

out, err := b.Get(context.Background(), txns[0].Entry.Key)
if err != nil {
t.Fatalf("unexpected error after failed put: %v", err)
}
if out != nil {
t.Fatal("expected response entry to be nil after a failed put")
}
}

func TestRaft_TransactionalBackend_LargeValue(t *testing.T) {
b, dir := getRaft(t, true, true)
defer os.RemoveAll(dir)
Expand Down

0 comments on commit cb06696

Please sign in to comment.