This is an automated email from the ASF dual-hosted git repository.

bteke pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/trunk by this push:
     new c6e716bf5bc YARN-11922. ResourceManager not update SecretManager 
keysize immediately if recovery is on (#8194)
c6e716bf5bc is described below

commit c6e716bf5bc8958a1f5fc63d1b2844a2f8f118be
Author: K0K0V0K <[email protected]>
AuthorDate: Tue Jan 27 16:07:04 2026 +0100

    YARN-11922. ResourceManager not update SecretManager keysize immediately if 
recovery is on (#8194)
    
    Problem Statement:
    I have a scenario where I need to migrate a YARN cluster to a FIPS 
140-3–compatible environment.
    For this, the AMRMTokenSecretManager must use secrets that are at least 112 
bits long. By default, the secret length is 64 bits. When I modify the key size 
and restart the cluster with recovery enabled, the state store reloads the old 
secret, which has a default lifetime of 24 hours. As a result, even though the 
cluster is configured to operate in FIPS 140-3–compatible mode, it continues to 
use a non-compliant secret.
    
    Solution:
    When the ResourceManager recovers, it should validate the secret size 
stored in the state store. If the stored secret size differs from the 
configured value, the secret should be forcibly regenerated and updated.
    
    Tested:
    Through manual testing, I verified that HIVE applications can run 
successfully both before and after the configuration change.
---
 .../hadoop/security/token/SecretManager.java       |  9 ++++++
 .../security/AMRMTokenSecretManager.java           | 36 +++++++++++++++++++---
 .../recovery/RMStateStoreTestBase.java             | 23 ++++++++++++++
 .../recovery/TestFSRMStateStore.java               |  1 +
 .../recovery/TestZKRMStateStore.java               |  1 +
 5 files changed, 65 insertions(+), 5 deletions(-)

diff --git 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/token/SecretManager.java
 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/token/SecretManager.java
index be3f964a086..3183f1fc0df 100644
--- 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/token/SecretManager.java
+++ 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/token/SecretManager.java
@@ -183,6 +183,15 @@ protected SecretKey generateSecret() {
     }
   }
 
+  /**
+   * Validate the secretKey length is equal to the selected config.
+   * @param secretKey secretKey
+   * @return true if the secretKey length is equal to the currently configured 
length
+   */
+  protected boolean validateSecretKeyLength(byte[] secretKey) {
+    return secretKey.length * 8 == selectedLength;
+  }
+
   /**
    * Compute HMAC of the identifier using the secret key and return the 
    * output as password
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/security/AMRMTokenSecretManager.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/security/AMRMTokenSecretManager.java
index 337b5851770..13abdbbb8dd 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/security/AMRMTokenSecretManager.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/security/AMRMTokenSecretManager.java
@@ -324,17 +324,16 @@ protected byte[] createPassword(AMRMTokenIdentifier 
identifier) {
   }
 
   public void recover(RMState state) {
-    if (state.getAMRMTokenSecretManagerState() != null) {
+    AMRMTokenSecretManagerState tokenState = getTokenState(state);
+    if (tokenState != null) {
       // recover the current master key
-      MasterKey currentKey =
-          state.getAMRMTokenSecretManagerState().getCurrentMasterKey();
+      MasterKey currentKey = tokenState.getCurrentMasterKey();
       this.currentMasterKey =
           new MasterKeyData(currentKey, createSecretKey(currentKey.getBytes()
             .array()));
 
       // recover the next master key if not null
-      MasterKey nextKey =
-          state.getAMRMTokenSecretManagerState().getNextMasterKey();
+      MasterKey nextKey = tokenState.getNextMasterKey();
       if (nextKey != null) {
         this.nextMasterKey =
             new MasterKeyData(nextKey, createSecretKey(nextKey.getBytes()
@@ -343,4 +342,31 @@ public void recover(RMState state) {
       }
     }
   }
+
+  private AMRMTokenSecretManagerState getTokenState(RMState state) {
+    AMRMTokenSecretManagerState result = 
state.getAMRMTokenSecretManagerState();
+    return result == null ? null : validateAndUpdateState(result);
+  }
+
+  private AMRMTokenSecretManagerState 
validateAndUpdateState(AMRMTokenSecretManagerState state) {
+    MasterKey currentKey = state.getCurrentMasterKey();
+    MasterKey nextKey = state.getNextMasterKey();
+    boolean updateRequired = false;
+    if (!validateMasterKey(currentKey)) {
+      state.setCurrentMasterKey(createNewMasterKey().getMasterKey());
+      updateRequired = true;
+    }
+    if (!validateMasterKey(nextKey)) {
+      state.setNextMasterKey(createNewMasterKey().getMasterKey());
+      updateRequired = true;
+    }
+    if (updateRequired) {
+      rmContext.getStateStore().storeOrUpdateAMRMTokenSecretManager(state, 
true);
+    }
+    return state;
+  }
+
+  private boolean validateMasterKey(MasterKey masterKey) {
+    return masterKey == null || 
validateSecretKeyLength(masterKey.getBytes().array());
+  }
 }
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/RMStateStoreTestBase.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/RMStateStoreTestBase.java
index 202ecf811b1..a23a350ffa9 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/RMStateStoreTestBase.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/RMStateStoreTestBase.java
@@ -41,8 +41,10 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
 import org.apache.hadoop.io.Text;
 import org.apache.hadoop.ipc.CallerContext;
+import org.apache.hadoop.security.token.SecretManager;
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.security.token.delegation.DelegationKey;
 import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
@@ -780,6 +782,27 @@ public void testAMRMTokenSecretManagerStateStore(
     store.close();
   }
 
+  public void testAMRMTokenSecretManagerStateStoreKeyLengthChange(
+      RMStateStoreHelper stateStoreHelper) throws Exception {
+    RMState rmState = stateStoreHelper.getRMStateStore().loadState();
+    AMRMTokenSecretManagerState state = 
rmState.getAMRMTokenSecretManagerState();
+    assertEquals(
+        
CommonConfigurationKeysPublic.HADOOP_SECURITY_SECRET_MANAGER_KEY_LENGTH_DEFAULT,
+        state.getCurrentMasterKey().getBytes().array().length * 8
+    );
+    Configuration configuration = new Configuration();
+    configuration.setInt(
+        
CommonConfigurationKeysPublic.HADOOP_SECURITY_SECRET_MANAGER_KEY_LENGTH_KEY, 
256);
+    SecretManager.update(configuration);
+    RMContext rmContext = mock(RMContext.class);
+    
when(rmContext.getStateStore()).thenReturn(stateStoreHelper.getRMStateStore());
+    Configuration conf = new YarnConfiguration();
+    AMRMTokenSecretManager appTokenMgr = new AMRMTokenSecretManager(conf, 
rmContext);
+    appTokenMgr.recover(rmState);
+    assertEquals(256,  rmState.getAMRMTokenSecretManagerState()
+        .getCurrentMasterKey().getBytes().array().length * 8);
+  }
+
   public void testReservationStateStore(
       RMStateStoreHelper stateStoreHelper) throws Exception {
     RMStateStore store = stateStoreHelper.getRMStateStore();
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestFSRMStateStore.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestFSRMStateStore.java
index d83b862896f..fc56238eb8d 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestFSRMStateStore.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestFSRMStateStore.java
@@ -215,6 +215,7 @@ public void testFSRMStateStore() throws Exception {
       testAMRMTokenSecretManagerStateStore(fsTester);
       testReservationStateStore(fsTester);
       testProxyCA(fsTester);
+      testAMRMTokenSecretManagerStateStoreKeyLengthChange(fsTester);
     } finally {
       cluster.shutdown();
     }
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestZKRMStateStore.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestZKRMStateStore.java
index 47ed3760842..d09a102720c 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestZKRMStateStore.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestZKRMStateStore.java
@@ -298,6 +298,7 @@ public void testZKRMStateStoreRealZK() throws Exception {
     ((TestZKRMStateStoreTester.TestZKRMStateStoreInternal)
         zkTester.getRMStateStore()).testRetryingCreateRootDir();
     testProxyCA(zkTester);
+    testAMRMTokenSecretManagerStateStoreKeyLengthChange(zkTester);
   }
 
   @Test


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to