Skip to content

Commit 81af932

Browse files
committed
ING-1313: Prevent potential deadlock from edge case
1 parent 1d5a0c9 commit 81af932

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

cbauthx/authcheck_cached.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,11 @@ func (a *AuthCheckCached) checkSlow(ctx context.Context, username string, passwo
111111
key, slowEntry, username, password)
112112
}
113113

114-
if slowEntry.PendingCh != nil {
115-
pendingCh := slowEntry.PendingCh
114+
pendingCh := slowEntry.PendingCh
116115

117-
a.slowLock.Unlock()
116+
a.slowLock.Unlock()
118117

118+
if pendingCh != nil {
119119
select {
120120
case <-pendingCh:
121121
case <-ctx.Done():
@@ -126,11 +126,16 @@ func (a *AuthCheckCached) checkSlow(ctx context.Context, username string, passwo
126126
}
127127
}
128128

129-
if slowEntry.ResolveErr != nil {
130-
return UserInfo{}, slowEntry.ResolveErr
129+
// pendingCh is guaranteed to only be closed after these fields have been
130+
// written so it is safe to read them having blocked on pendingCh above.
131+
resolveErr := slowEntry.ResolveErr
132+
resolveInfo := slowEntry.Info
133+
134+
if resolveErr != nil {
135+
return UserInfo{}, resolveErr
131136
}
132137

133-
return *slowEntry.Info, nil
138+
return *resolveInfo, nil
134139
}
135140

136141
func (a *AuthCheckCached) checkThread(
@@ -170,6 +175,9 @@ func (a *AuthCheckCached) checkThread(
170175
}
171176

172177
pendingCh := slowEntry.PendingCh
178+
179+
// Set the pending channel for the slow entry to nil to prevent checkThreads
180+
// against the same slow entry from trying to close a closed channel.
173181
slowEntry.PendingCh = nil
174182

175183
a.rebuildFastCacheLocked()

0 commit comments

Comments
 (0)