Conversation
added 2 commits
April 15, 2026 14:18
…ryAuthority - Extract authority.getAuthorityURL() outside synchronized(sLock) in Authority.isKnownAuthority() to avoid lock-ordering inversion - Extract authority.getAuthorityURL() outside synchronized scope in AzureActiveDirectory.ensureCloudDiscoveryForAuthority(Authority) - Remove synchronized from read-only ConcurrentHashMap methods in AzureActiveDirectory (hasCloudHost, getAzureActiveDirectoryCloud, getAzureActiveDirectoryCloudFromHostName, isValidCloudHost) - Remove synchronized from AzureActiveDirectoryAuthority.getAzureActiveDirectoryCloud() - Add null check for authorityUrl in isKnownAuthority() - Improve error handling in getKnownAuthorityResult(): propagate original discovery exception instead of replacing with UNKNOWN_AUTHORITY - Make KnownAuthorityResult fields final - Add 5 concurrency regression tests in AzureActiveDirectoryTest - Expand AuthorityKnownAuthorityTest with sovereign cloud, error propagation, and mock-based getKnownAuthorityResult tests AB#3578299
|
❌ Invalid work item number: AB#3578299 Click here to learn more. |
|
✅ Work item link check complete. Description contains link AB#3578299 to an Azure Boards work item. |
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Fixes a lock-order inversion (ABBA deadlock) between AzureActiveDirectory and AzureActiveDirectoryAuthority by moving polymorphic getAuthorityURL() calls out of synchronized scopes and reducing unnecessary synchronization in read-only cloud map accessors, with added regression tests around concurrency and error propagation.
Changes:
- Prevent deadlock by resolving
authority.getAuthorityURL()outside locks inAuthority.isKnownAuthority()andAzureActiveDirectory.ensureCloudDiscoveryForAuthority(Authority). - Remove
synchronizedfrom read-only methods backed byConcurrentHashMapand adjust known-authority discovery error propagation behavior. - Add/expand Kotlin tests for concurrency deadlock regression and known-authority result behaviors.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| common4j/src/test/com/microsoft/identity/common/java/providers/microsoft/azureactivedirectory/AzureActiveDirectoryTest.kt | Adds concurrency regression/stress tests for deadlock and concurrent read/write behavior. |
| common4j/src/test/com/microsoft/identity/common/java/authorities/AuthorityKnownAuthorityTest.kt | Expands tests for null handling, sovereign clouds, and discovery error-code propagation. |
| common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/azureactivedirectory/AzureActiveDirectory.java | Removes synchronization from read-only cloud map API and avoids lock inversion in authority-based discovery. |
| common4j/src/main/com/microsoft/identity/common/java/authorities/AzureActiveDirectoryAuthority.java | Removes synchronized from a static cloud lookup helper. |
| common4j/src/main/com/microsoft/identity/common/java/authorities/Authority.java | Avoids lock inversion in isKnownAuthority, improves getKnownAuthorityResult error propagation, finalizes result fields. |
| changelog.txt | Documents the patch-level deadlock fix. |
added 2 commits
April 15, 2026 14:54
- Fix race in isValidCloudHost: store cloud in local variable and null-check before calling isValidated() to prevent NPE - Fix comment: getAuthorityUri() -> getAuthorityURL() - Remove brittle PR#3027 reference from comment - Add clearKnownAuthorities() test helper to Authority and use in @after to prevent state leaking between tests - Mark all concurrency test threads as daemon to prevent JVM hang on deadlock
mAudience is only set during construction/deserialization and never mutated after. The synchronized on this instance method added lock contention with no thread-safety benefit, and created an unnecessary instance monitor → AzureActiveDirectory.class lock ordering.
mohitc1
pushed a commit
that referenced
this pull request
Apr 15, 2026
…eDirectoryAuthority Cherry-picked from mchand/cloud-discovery-deadlock-fix (PR #3082). - Extract authority.getAuthorityURL() outside synchronized scopes in Authority.isKnownAuthority() and AzureActiveDirectory.ensureCloudDiscoveryForAuthority() - Remove synchronized from read-only ConcurrentHashMap methods in AzureActiveDirectory - Remove synchronized from AzureActiveDirectoryAuthority.getAzureActiveDirectoryCloud() and isSameCloudAsAuthority() - Fix race in isValidCloudHost() (null-check before isValidated()) - Add clearKnownAuthorities() test helper - Improve error handling in getKnownAuthorityResult() - Add concurrency regression tests AB#3578299
mohitc1
pushed a commit
that referenced
this pull request
Apr 15, 2026
…eDirectoryAuthority Cherry-picked from mchand/cloud-discovery-deadlock-fix (PR #3082). - Extract authority.getAuthorityURL() outside synchronized scopes in Authority.isKnownAuthority() and AzureActiveDirectory.ensureCloudDiscoveryForAuthority() - Remove synchronized from read-only ConcurrentHashMap methods in AzureActiveDirectory - Remove synchronized from AzureActiveDirectoryAuthority.getAzureActiveDirectoryCloud() and isSameCloudAsAuthority() - Fix race in isValidCloudHost() (null-check before isValidated()) - Add clearKnownAuthorities() test helper - Improve error handling in getKnownAuthorityResult() - Add concurrency regression tests AB#3578299
siddhijain
approved these changes
Apr 15, 2026
rpdome
approved these changes
Apr 15, 2026
mohitc1
added a commit
that referenced
this pull request
Apr 15, 2026
…ureActiveDirectoryAuthority, Fixes AB#3578299 (#3083) ## Hotfix for release/24.1.1 Cherry-pick of PR #3082 (dev branch fix) onto \working/release/24.1.1\. ### Problem ABBA deadlock between \AzureActiveDirectory.class\ and \AzureActiveDirectoryAuthority.class\ monitors under high concurrency (multiple apps calling into Broker simultaneously), causing ANR in Microsoft Authenticator. ### Changes - Extract \�uthority.getAuthorityURL()\ outside synchronized scopes - Remove \synchronized\ from read-only \ConcurrentHashMap\ methods - Remove \synchronized\ from \AzureActiveDirectoryAuthority.getAzureActiveDirectoryCloud()\ and \isSameCloudAsAuthority()\ - Fix race in \isValidCloudHost()\ (null-check before \isValidated()\) - Improve error handling in \getKnownAuthorityResult()\ - Add concurrency regression tests ### Testing All \common4j\ tests pass on this branch. [AB#3578299](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3578299) Co-authored-by: Mohit <mchand@microsoft.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes an ABBA deadlock between
AzureActiveDirectory.classandAzureActiveDirectoryAuthority.classmonitors, discovered during ANR investigation on Microsoft Authenticator (Broker v16.0.0). Under high concurrency (multiple apps calling into Broker simultaneously), two threads could deadlock:isKnownAuthority):sLock→authority.getAuthorityURL()→AzureActiveDirectoryAuthority.class→AzureActiveDirectory.classensureCloudDiscoveryForAuthority):AzureActiveDirectory.class→authority.getAuthorityURL()→AzureActiveDirectoryAuthority.classChanges
Source (3 files)
Authority.java
authority.getAuthorityURL()outsidesynchronized(sLock)inisKnownAuthority()authorityUrlgetKnownAuthorityResult(): propagate original discovery exception error code instead of replacing withUNKNOWN_AUTHORITYKnownAuthorityResultfieldsfinalAzureActiveDirectory.java
synchronizedfrom read-onlyConcurrentHashMapmethods:hasCloudHost,getAzureActiveDirectoryCloud,getAzureActiveDirectoryCloudFromHostName,isValidCloudHostauthority.getAuthorityURL()outside synchronized scope inensureCloudDiscoveryForAuthority(Authority)AzureActiveDirectoryAuthority.java
synchronizedfromprivate static getAzureActiveDirectoryCloud()Tests (2 files)
AzureActiveDirectoryTest.kt — 5 concurrency regression tests:
isKnownAuthorityandensureCloudDiscoverygetAuthorityURL()callsAuthorityKnownAuthorityTest.kt — expanded:
Linked Work Items
AB#3578299