You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Race explanation inside HasLink() function with goroutines A and B:
Enforce A: Enter HasLink(). Role does not exist, is added to map temporarily && defer rm.removeRole() called
Enforce A: hasLinkHelper iterates over roles via sync.Map.Range() recursively
Enforce B: Temp role exists, fetch it.
Enforce A: Exit function, removeRole() called.
Enforce B: hasLinkHelper iterates over roles but the temp role no longer exists
Enforce A: allow: true
Enforce B: allow: false
Furthermore once this happens, the calculation is cached in GenerateGFunction and also in getAndStoreMatcherExpression(), all further Enforce() calls for that set of parameters will incorrectly return a cached false response.
To Reproduce
This behaviour does not occur all the time, but by disabling cache inside GenerateGFunction it is possible to reproduce it reliably:
Enforcer always returns true when correct policies are in place.
Actual behavior
Enforcer sometimes returns false even when correct policies are in place and it may cache the result to continue returning false incorrectly.
Environment
OS: macOS and Linux
Possible solutions
It seems that feasible solutions may be having a mutex on HasLink() or not storing temporary roles in a shared map and having a temporary map defined inside the scope of the function.
The text was updated successfully, but these errors were encountered:
Describe the bug
Setup:
AddNamedMatchingFunc()
used (e.g. keyMatch2, keyMatch4)The bug is reproduced when calling
Enforce()
with the same parameters concurrently.It boils down to this path being executed concurrently:
GenerateGFunction()->HasLink()->defer rm.removeRole().
Race explanation inside
HasLink()
function with goroutines A and B:HasLink()
. Role does not exist, is added to map temporarily &&defer rm.removeRole()
calledhasLinkHelper
iterates over roles viasync.Map.Range()
recursivelyremoveRole()
called.hasLinkHelper
iterates over roles but the temp role no longer existsallow: true
allow: false
Furthermore once this happens, the calculation is cached in
GenerateGFunction
and also in getAndStoreMatcherExpression(), all furtherEnforce()
calls for that set of parameters will incorrectly return a cachedfalse
response.To Reproduce
This behaviour does not occur all the time, but by disabling cache inside
GenerateGFunction
it is possible to reproduce it reliably:make test
Check README in the Metrika-Inc/casbin-race repository for more details.
Expected behavior
Enforcer always returns true when correct policies are in place.
Actual behavior
Enforcer sometimes returns false even when correct policies are in place and it may cache the result to continue returning false incorrectly.
Environment
Possible solutions
It seems that feasible solutions may be having a mutex on
HasLink()
or not storing temporary roles in a shared map and having a temporary map defined inside the scope of the function.The text was updated successfully, but these errors were encountered: