From f6acc9d28bf6ed79d4d99ba91e928353774e89b4 Mon Sep 17 00:00:00 2001 From: Ivan Kozlovic Date: Thu, 20 Jan 2022 13:38:31 -0700 Subject: [PATCH] [FIXED] Possible deadlock This is due to a re-entrant RLock(). It works sometimes, but if there is a go routine requesting the write lock, then the second RLock() will not be granted which will lead to a deadlock. In summary: one should never make re-entrant RLock calls. Signed-off-by: Ivan Kozlovic --- server/accounts.go | 11 +++++++++-- server/auth.go | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/server/accounts.go b/server/accounts.go index d2102589..eae82105 100644 --- a/server/accounts.go +++ b/server/accounts.go @@ -731,9 +731,16 @@ func (a *Account) hasMappings() bool { return false } a.mu.RLock() - n := len(a.mappings) + hm := a.hasMappingsLocked() a.mu.RUnlock() - return n > 0 + return hm +} + +// Indicates we have mapping entries. +// The account has been verified to be non-nil. +// Read or Write lock held on entry. +func (a *Account) hasMappingsLocked() bool { + return len(a.mappings) > 0 } // This performs the logic to map to a new dest subject based on mappings. diff --git a/server/auth.go b/server/auth.go index f2e76692..ca3fe5b9 100644 --- a/server/auth.go +++ b/server/auth.go @@ -706,7 +706,7 @@ func (s *Server) processClientOrLeafAuthentication(c *client, opts *Options) boo acc.mu.RLock() c.Debugf("Authenticated JWT: %s %q (claim-name: %q, claim-tags: %q) "+ "signed with %q by Account %q (claim-name: %q, claim-tags: %q) signed with %q has mappings %t accused %p", - c.kindString(), juc.Subject, juc.Name, juc.Tags, juc.Issuer, issuer, acc.nameTag, acc.tags, acc.Issuer, acc.hasMappings(), acc) + c.kindString(), juc.Subject, juc.Name, juc.Tags, juc.Issuer, issuer, acc.nameTag, acc.tags, acc.Issuer, acc.hasMappingsLocked(), acc) acc.mu.RUnlock() return true }