Skip to content

Commit 437eae0

Browse files
committed
Transit: fix race in the key update api
- The key update API would release the lock a little too early after it persisted the update so the reference could be updated when it was preparing the response to the caller across updates and/or key rotations - The storage updates were okay, just the response back to the caller of the update might see a mixture of different updates
1 parent c855f6e commit 437eae0

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

builtin/logical/transit/path_keys.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,10 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d *
260260
if p == nil {
261261
return nil, fmt.Errorf("error generating key: returned policy was nil")
262262
}
263-
if b.System().CachingDisabled() {
264-
p.Unlock()
263+
if !b.System().CachingDisabled() {
264+
p.Lock(true)
265265
}
266+
defer p.Unlock()
266267

267268
resp, err := b.formatKeyPolicy(p, nil)
268269
if err != nil {

builtin/logical/transit/path_keys_config_test.go

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@ import (
1010
"fmt"
1111
"strconv"
1212
"strings"
13+
"sync"
1314
"testing"
1415
"time"
1516

16-
uuid "github.com/hashicorp/go-uuid"
17+
"github.com/hashicorp/go-uuid"
1718
"github.com/hashicorp/vault/api"
1819
vaulthttp "github.com/hashicorp/vault/http"
1920
"github.com/hashicorp/vault/sdk/logical"
2021
"github.com/hashicorp/vault/vault"
22+
"github.com/stretchr/testify/require"
2123
)
2224

2325
func TestTransit_ConfigSettings(t *testing.T) {
@@ -406,3 +408,51 @@ func TestTransit_UpdateKeyConfigWithAutorotation(t *testing.T) {
406408
})
407409
}
408410
}
411+
412+
// TestTransitLockRace expose race condition fixed in VAULT-23977
413+
func TestTransitLockRace(t *testing.T) {
414+
b, s := createBackendWithStorage(t)
415+
416+
createReq := &logical.Request{
417+
Operation: logical.UpdateOperation,
418+
Path: "keys/test",
419+
Storage: s,
420+
}
421+
422+
_, err := b.HandleRequest(context.Background(), createReq)
423+
require.NoError(t, err, "failed creating key")
424+
425+
wg := sync.WaitGroup{}
426+
wg.Add(2)
427+
// Expose race between key rotation and key update api
428+
go func() {
429+
for i := 0; i < 100; i++ {
430+
rotateKeyReq := &logical.Request{
431+
Operation: logical.UpdateOperation,
432+
Path: "keys/test/rotate",
433+
Storage: s,
434+
}
435+
436+
_, err := b.HandleRequest(context.Background(), rotateKeyReq)
437+
require.NoError(t, err, "failed rotating key")
438+
}
439+
440+
wg.Done()
441+
}()
442+
443+
go func() {
444+
for i := 0; i < 100; i++ {
445+
updateKeyReq := &logical.Request{
446+
Operation: logical.UpdateOperation,
447+
Path: "keys/test",
448+
Storage: s,
449+
}
450+
451+
_, err := b.HandleRequest(context.Background(), updateKeyReq)
452+
require.NoError(t, err, "failed updating key")
453+
}
454+
wg.Done()
455+
}()
456+
457+
wg.Wait()
458+
}

0 commit comments

Comments
 (0)