Always call tieProfileLockIfNecessary() under mSpManager lock

tieProfileLockIfNecessary() runs under the mSpManager lock when a user's
LSKF is changed, but not when it's executed by onUserUnlocking().  In
the latter case, a race is possible where tieProfileLockToParent() tries
to generate an auth-bound key for a parent user whose LSKF has just been
removed by a concurrent thread.  This fails and throws an exception,
crashing system_server.  Fix this by ensuring that the mSpManager lock
is always held during tieProfileLockIfNecessary().

Bug: 355905501
Flag: android.app.admin.flags.fix_race_condition_in_tie_profile_lock
Test: atest FrameworksServicesTests:com.android.server.locksettings
Test: atest CtsDevicePolicyTestCases # 6 test cases failed both before and after
Change-Id: I5f8c1bcc206460c1480ce58c846e32d91898c4ce
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index 17df513..4a45a7a 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -100,6 +100,16 @@
 }
 
 flag {
+  name: "fix_race_condition_in_tie_profile_lock"
+  namespace: "enterprise"
+  description: "Fix race condition in tieProfileLockIfNecessary()"
+  bug: "355905501"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "quiet_mode_credential_bug_fix"
   namespace: "enterprise"
   description: "Guards a bugfix that ends the credential input flow if the managed user has not stopped."
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 62731ab..3a7eece 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -879,8 +879,14 @@
                 // Hide notification first, as tie profile lock takes time
                 hideEncryptionNotification(new UserHandle(userId));
 
-                if (isCredentialSharableWithParent(userId)) {
-                    tieProfileLockIfNecessary(userId, LockscreenCredential.createNone());
+                if (android.app.admin.flags.Flags.fixRaceConditionInTieProfileLock()) {
+                    synchronized (mSpManager) {
+                        tieProfileLockIfNecessary(userId, LockscreenCredential.createNone());
+                    }
+                } else {
+                    if (isCredentialSharableWithParent(userId)) {
+                        tieProfileLockIfNecessary(userId, LockscreenCredential.createNone());
+                    }
                 }
             }
         });
@@ -1245,7 +1251,13 @@
                 mStorage.removeChildProfileLock(userId);
                 removeKeystoreProfileKey(userId);
             } else {
-                tieProfileLockIfNecessary(userId, profileUserPassword);
+                if (android.app.admin.flags.Flags.fixRaceConditionInTieProfileLock()) {
+                    synchronized (mSpManager) {
+                        tieProfileLockIfNecessary(userId, profileUserPassword);
+                    }
+                } else {
+                    tieProfileLockIfNecessary(userId, profileUserPassword);
+                }
             }
         } catch (IllegalStateException e) {
             setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, old, userId);