Skip to content

Commit

Permalink
Fix a transit deadlock (#13795)
Browse files Browse the repository at this point in the history
* Fix a transit deadlock caused by indefinite lock holding in key autorotation.

* Move down manual policy locking in transit autorotation to avoid NPE.

* Wrap conditional transit key autorotation in a function to allow for cleaner policy lock management.

* Remove a dnagling continue statement from transit key autorotation.
  • Loading branch information
schultz-is authored Jan 27, 2022
1 parent afb9449 commit b390ef9
Showing 1 changed file with 28 additions and 21 deletions.
49 changes: 28 additions & 21 deletions builtin/logical/transit/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,29 +231,36 @@ func (b *backend) autoRotateKeys(ctx context.Context, req *logical.Request) erro
continue
}

// If the policy's automatic rotation interval is 0, it should not
// automatically rotate.
if p.AutoRotateInterval == 0 {
continue
}

// Retrieve the latest version of the policy and determine if it is time to rotate.
latestKey := p.Keys[strconv.Itoa(p.LatestVersion)]
if time.Now().After(latestKey.CreationTime.Add(p.AutoRotateInterval)) {
if b.Logger().IsDebug() {
b.Logger().Debug("automatically rotating key", "key", key)
}
if !b.System().CachingDisabled() {
p.Lock(true)
}
err = p.Rotate(ctx, req.Storage, b.GetRandomReader())
p.Unlock()
if err != nil {
errs = multierror.Append(errs, err)
continue
}
err = b.rotateIfRequired(ctx, req, key, p)
if err != nil {
errs = multierror.Append(errs, err)
}
}

return errs.ErrorOrNil()
}

// rotateIfRequired rotates a key if it is due for autorotation.
func (b *backend) rotateIfRequired(ctx context.Context, req *logical.Request, key string, p *keysutil.Policy) error {
if !b.System().CachingDisabled() {
p.Lock(true)
}
defer p.Unlock()

// If the policy's automatic rotation interval is 0, it should not
// automatically rotate.
if p.AutoRotateInterval == 0 {
return nil
}

// Retrieve the latest version of the policy and determine if it is time to rotate.
latestKey := p.Keys[strconv.Itoa(p.LatestVersion)]
if time.Now().After(latestKey.CreationTime.Add(p.AutoRotateInterval)) {
if b.Logger().IsDebug() {
b.Logger().Debug("automatically rotating key", "key", key)
}
return p.Rotate(ctx, req.Storage, b.GetRandomReader())

}
return nil
}

0 comments on commit b390ef9

Please sign in to comment.