Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Race condition on ConfigurationManager._syncAfter #2900

Open
1 of 14 tasks
bruno-brant opened this issue Oct 11, 2024 · 5 comments · May be fixed by #2988
Open
1 of 14 tasks

[Bug] Race condition on ConfigurationManager._syncAfter #2900

bruno-brant opened this issue Oct 11, 2024 · 5 comments · May be fixed by #2988
Assignees
Labels
Bug Product is not functioning as expected P1 More important, prioritize highly

Comments

@bruno-brant
Copy link

Which version of Microsoft.IdentityModel are you using?
Microsoft.IdentityModel 8.1.2

Where is the issue?

  • M.IM.JsonWebTokens
  • M.IM.KeyVaultExtensions
  • M.IM.Logging
  • M.IM.ManagedKeyVaultSecurityKey
  • M.IM.Protocols
  • M.IM.Protocols.OpenIdConnect
  • M.IM.Protocols.SignedHttpRequest
  • M.IM.Protocols.WsFederation
  • M.IM.TestExtensions
  • M.IM.Tokens
  • M.IM.Tokens.Saml
  • M.IM.Validators
  • M.IM.Xml
  • S.IM.Tokens.Jwt
  • Other (please describe)

Description

Every calling thread to ConfigurationManager.GetConfigurationAsync will result in a read to _syncAfter to check if a sync should be started; later, a background thread will update _syncAfter with the new sync time. syncAfter is a DateTimeOffset, a struct, so writes to it aren't atomic, so there's a possibility that the calling thread will read corrupt data.

Possible solution

  • Rewrite _syncAfter so that it can be atomically read/written - we could refactor it to be total seconds (int32) or any other type that is atomic.
  • Rearchitect the metadata refresh to happen completely in the background, to avoid every calling thread having to access the syncAfter variable.

Additional context / logs / screenshots / links to code

@jennyf19 jennyf19 added P1 More important, prioritize highly Bug Product is not functioning as expected and removed needs attention untriaged labels Oct 11, 2024
@jennyf19
Copy link
Collaborator

FYI @brentschmaltz

@brentschmaltz
Copy link
Member

I like the idea to use Epoch time as a long.

@bruno-brant
Copy link
Author

bruno-brant commented Oct 14, 2024

I like the idea to use Epoch time as a long.

Longs can still cause an issue in 32-bit architectures unless we use Interlocked or any other synchronization strategy. A int32 is always atomic.

Given the use case, maybe an int32 would suffice? I know the max time shouldn't larger than an int.MaxValue, not sure if the subtraction is cheaper than an interlocked though.

@keegan-caruso
Copy link
Contributor

@brentschmaltz We don't need to store the epoch time, just the offset, which should always be capturable in an int. I think this is the point @bruno-brant is trying to make.

@brentschmaltz
Copy link
Member

@keegan-caruso that makes sense also, hadn't thought about 32bit architectures, that is a good point and should be considered.

@brentschmaltz brentschmaltz self-assigned this Oct 22, 2024
@pmaytak pmaytak linked a pull request Nov 8, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Product is not functioning as expected P1 More important, prioritize highly
Projects
None yet
4 participants