Skip to content

Commit

Permalink
Fix #2075 Slow startup because of low entropy for PRNG (#2318) (#2335)
Browse files Browse the repository at this point in the history
* Fix hang-up due to blocking PRNG returned by SecureRandom.getInstanceStrong()
Fixes #2075

(cherry picked from commit 4ef3517)
Signed-off-by: Zuplyx <patrick_98@t-online.de>
  • Loading branch information
Zuplyx authored Dec 22, 2024
1 parent 452ffdd commit a96b873
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024 Contributors to the Eclipse Foundation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -75,7 +76,7 @@ public class SystemProperties {

/**
* This system property can be set to override target server platform set by the Java EE container
* with the one either set in persistence.xml or auto detected.
* with the one either set in persistence.xml or auto-detected.
*/
public static final String ENFORCE_TARGET_SERVER = "eclipselink.target-server.enforce";

Expand All @@ -94,7 +95,7 @@ public class SystemProperties {
public static final String CONVERSION_USE_DEFAULT_TIMEZONE = "org.eclipse.persistence.conversion.useDefaultTimeZoneForJavaTime";

/**
* This property can be set to <code>false</code> to enable UPDATE call to set
* This property can be set to {@code false} to enable UPDATE call to set
* foreign key value in the target row in unidirectional 1-Many mapping
* with not nullable FK. In previous versions of EclipseLink this was
* the default behaviour.
Expand All @@ -104,71 +105,71 @@ public class SystemProperties {

/**
* This system property in milliseconds can control thread management in org.eclipse.persistence.internal.helper.ConcurrencyManager.
* It control how much time loop wait before it try acquire lock for current thread again. It value is set above above 0 dead lock detection
* It controls how much time loop wait before it tries to acquire lock for current thread again. If the value is set above 0 deadlock detection
* mechanism and related extended logging will be activated.
* Default value is 0 (unit is ms). Allowed values are: long
*/
public static final String CONCURRENCY_MANAGER_ACQUIRE_WAIT_TIME = "eclipselink.concurrency.manager.waittime";

/**
* This system property in milliseconds can control thread management in org.eclipse.persistence.internal.helper.ConcurrencyManager.
* It control how much time ConcurrencyManager will wait before it will identify, that thread which builds new object/entity instance
* should be identified as a potential dead lock source. It leads into some additional log messages.
* It controls how much time ConcurrencyManager will wait before it will identify, that thread which builds new object/entity instance
* should be identified as a potential deadlock source. It leads into some additional log messages.
* Default value is 0 (unit is ms). In this case extended logging is not active. Allowed values are: long
*/
public static final String CONCURRENCY_MANAGER_BUILD_OBJECT_COMPLETE_WAIT_TIME = "eclipselink.concurrency.manager.build.object.complete.waittime";

/**
* This system property in milliseconds can control thread management in org.eclipse.persistence.internal.helper.ConcurrencyManager.
* It control how long we are willing to wait before firing up an exception
* It controls how long we are willing to wait before firing up an exception
* Default value is 40000 (unit is ms). Allowed values are: long
*/
public static final String CONCURRENCY_MANAGER_MAX_SLEEP_TIME = "eclipselink.concurrency.manager.maxsleeptime";

/**
* This system property in milliseconds can control thread management in org.eclipse.persistence.internal.helper.ConcurrencyManager and org.eclipse.persistence.internal.helper.ConcurrencyUtil.
* It control how frequently the tiny dump log message is created.
* It controls how frequently the tiny dump log message is created.
* Default value is 40000 (unit is ms). Allowed values are: long
*/
public static final String CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_TINY_MESSAGE = "eclipselink.concurrency.manager.maxfrequencytodumptinymessage";

/**
* This system property in milliseconds can control thread management in org.eclipse.persistence.internal.helper.ConcurrencyManager and org.eclipse.persistence.internal.helper.ConcurrencyUtil.
* It control how frequently the massive dump log message is created.
* It controls how frequently the massive dump log message is created.
* Default value is 60000 (unit is ms). Allowed values are: long
*/
public static final String CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_MASSIVE_MESSAGE = "eclipselink.concurrency.manager.maxfrequencytodumpmassivemessage";

/**
* <p>
* This property control (enable/disable) if <code>InterruptedException</code> fired when dead-lock diagnostic is enabled.
* This property control (enable/disable) if {@code InterruptedException} fired when dead-lock diagnostic is enabled.
* <p>
* <b>Allowed Values</b> (case sensitive String)<b>:</b>
* <ul>
* <li>"<code>false</code>" - if aborting frozen thread is not effective it is preferable to not fire the interrupted exception let the system
* <li>"{@code false}" - if aborting frozen thread is not effective it is preferable to not fire the interrupted exception let the system
* In the places where use this property normally if a thread is stuck it is because it is doing object building.
* Blowing the threads ups is not that dangerous. It can be very dangerous for production if the dead lock ends up
* not being resolved because the productive business transactions will become cancelled if the application has a
* limited number of retries to for example process an MDB. However, the code spots where we use this constant are
* not as sensible as when the write lock manager is starving to run commit.
* <li>"<code>true</code>" (DEFAULT) - if we want the to fire up an exception to try to get the current thread to release all of its acquired locks and allow other
* <li>"{@code true}" (DEFAULT) - if we want the to fire up an exception to try to get the current thread to release all of its acquired locks and allow other
* threads to progress.
* </ul>
*/
public static final String CONCURRENCY_MANAGER_ALLOW_INTERRUPTED_EXCEPTION = "eclipselink.concurrency.manager.allow.interruptedexception";

/**
* <p>
* This property control (enable/disable) if <code>ConcurrencyException</code> fired when dead-lock diagnostic is enabled.
* This property control (enable/disable) if {@code ConcurrencyException} fired when dead-lock diagnostic is enabled.
* <p>
* <b>Allowed Values</b> (case sensitive String)<b>:</b>
* <ul>
* <li>"<code>false</code>" - if aborting frozen thread is not effective it is preferable to not fire the concurrency exception let the system
* <li>"{@code false}" - if aborting frozen thread is not effective it is preferable to not fire the concurrency exception let the system
* freeze and die and force the administration to kill the server. This is preferable to aborting the transactions
* multiple times without success in resolving the dead lock and having business critical messages that after 3 JMS
* retries are discarded out. Failing to resolve a dead lock can have terrible impact in system recovery unless we
* have infinite retries for the business transactions.
* <li>"<code>true</code>" (DEFAULT) - if we want the to fire up an exception to try to get the current thread to release all of its acquired
* <li>"{@code true}" (DEFAULT) - if we want the to fire up an exception to try to get the current thread to release all of its acquired
* locks and allow other threads to progress.
* </ul>
*/
Expand All @@ -180,8 +181,8 @@ public class SystemProperties {
* <p>
* <b>Allowed Values</b> (case sensitive String)<b>:</b>
* <ul>
* <li>"<code>false</code>" (DEFAULT) - don't collect debug/trace information during ReadLock acquisition
* <li>"<code>true</code>" - collect debug/trace information during ReadLock acquisition. Has negative impact to the performance.
* <li>"{@code false}" (DEFAULT) - don't collect debug/trace information during ReadLock acquisition
* <li>"{@code true}" - collect debug/trace information during ReadLock acquisition. Has negative impact to the performance.
* </ul>
*/
public static final String CONCURRENCY_MANAGER_ALLOW_STACK_TRACE_READ_LOCK = "eclipselink.concurrency.manager.allow.readlockstacktrace";
Expand All @@ -192,13 +193,13 @@ public class SystemProperties {
* </p>
* Object building see {@link org.eclipse.persistence.internal.descriptors.ObjectBuilder} could be one of the
* primary sources pressure on concurrency manager. Most of the cache key acquisition and releasing is taking place during object building.
* Enable <code>true</code> this property to try reduce the likelihood of having dead locks is to allow less threads to start object
* Enable {@code true} this property to try reduce the likelihood of having dead locks is to allow less threads to start object
* building in parallel. In this case there should be negative impact to the performance.
* Note: Parallel access to the same entity/entity tree from different threads is not recommended technique in EclipseLink.
* <ul>
* <li>"<code>true</code>" - means we want to override vanilla behavior and use a semaphore to not allow too many
* <li>"{@code true}" - means we want to override vanilla behavior and use a semaphore to not allow too many
* threads in parallel to do object building
* <li>"<code>false</code>" (DEFAULT) - means just go ahead and try to build the object without any semaphore (false is
* <li>"{@code false}" (DEFAULT) - means just go ahead and try to build the object without any semaphore (false is
* vanilla behavior).
* </ul>
*/
Expand All @@ -215,9 +216,9 @@ public class SystemProperties {
* one-to-many relations of master detail being enriched with more details on this master).
* Note: Parallel access to the same entity/entity tree from different threads is not recommended technique in EclipseLink.
* <ul>
* <li>"<code>true</code>" - means we want to override vanilla behavior and use a semaphore to not allow too many
* <li>"{@code true}" - means we want to override vanilla behavior and use a semaphore to not allow too many
* threads. In this case there should be negative impact to the performance.
* <li>"<code>false</code>" (DEFAULT) - means just go ahead and try to build the object without any semaphore (false is
* <li>"{@code false}" (DEFAULT) - means just go ahead and try to build the object without any semaphore (false is
* vanilla behavior).
* </ul>
*/
Expand All @@ -226,17 +227,17 @@ public class SystemProperties {
/**
* <p>
* This property control number of threads in semaphore in {@link org.eclipse.persistence.internal.descriptors.ObjectBuilder}
* If "eclipselink.concurrency.manager.object.building.semaphore" property is <code>true</code> default value is 10. Allowed values are: int
* If "eclipselink.concurrency.manager.object.building.semaphore" property is <code>false</code> (DEFAULT) number of threads is unlimited.
* If "eclipselink.concurrency.manager.object.building.semaphore" property is {@code true} default value is 10. Allowed values are: int
* If "eclipselink.concurrency.manager.object.building.semaphore" property is {@code false} (DEFAULT) number of threads is unlimited.
* </p>
*/
public static final String CONCURRENCY_MANAGER_OBJECT_BUILDING_NO_THREADS = "eclipselink.concurrency.manager.object.building.no.threads";

/**
* <p>
* This property control number of threads in semaphore in {@link org.eclipse.persistence.internal.helper.WriteLockManager#acquireRequiredLocks}
* If "eclipselink.concurrency.manager.write.lock.manager.semaphore" property is <code>true</code> default value is 2. Allowed values are: int
* If "eclipselink.concurrency.manager.write.lock.manager.semaphore" property is <code>false</code> (DEFAULT) number of threads is unlimited.
* If "eclipselink.concurrency.manager.write.lock.manager.semaphore" property is {@code true} default value is 2. Allowed values are: int
* If "eclipselink.concurrency.manager.write.lock.manager.semaphore" property is {@code false} (DEFAULT) number of threads is unlimited.
* </p>
*/
public static final String CONCURRENCY_MANAGER_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS_NO_THREADS = "eclipselink.concurrency.manager.write.lock.manager.no.threads";
Expand Down Expand Up @@ -265,12 +266,25 @@ public class SystemProperties {
* <p>
* <b>Allowed Values</b> (case sensitive String)<b>:</b>
* <ul>
* <li>"<code>eclipselink</code>" (DEFAULT) - use ASM implementation from <i>org.eclipse.persistence.asm</i> project.</li>
* <li>"<code>ow2</code>" - use ASM implementation from <i>org.ow2.asm</i> project.</li>
* <li>"{@code eclipselink}" (DEFAULT) - use ASM implementation from <i>org.eclipse.persistence.asm</i> project.</li>
* <li>"{@code ow2}" - use ASM implementation from <i>org.ow2.asm</i> project.</li>
* </ul>
*/
public static final String ASM_SERVICE = "eclipselink.asm.service";

/**
* <p>
* This property controls the random number generator (RNG) used for password encryption.
* <p>
* <b>Allowed Values</b> (case sensitive String)<b>:</b>
* <ul>
* <li>"{@code false}" (DEFAULT) - use default RNG of Java platform
* <li>"{@code true}" - use RNG indicated by the securerandom.strongAlgorithms security property of Java platform
* </ul>
*/
public static final String SECURITY_ENCRYPTOR_USE_STRONG_RANDOM_NUMBER_GENERATOR = "eclipselink.security.encryptor.use.strong.random.number.generator";


/**
* @deprecated This constructor will be marked private and the class final. It is not designed for extensibility.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024 Contributors to the Eclipse Foundation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -14,6 +15,7 @@
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.security;

import org.eclipse.persistence.config.SystemProperties;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.helper.Helper;
Expand Down Expand Up @@ -124,10 +126,17 @@ private static SecretKey getAESGCMMultitasker() throws Exception {
private static byte[] getIvGCM() {
byte[] ivGCM = new byte[IV_GCM_LENGTH];
SecureRandom random = null;
try {
random = SecureRandom.getInstanceStrong();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
String useStrongRNG = PrivilegedAccessHelper.getSystemProperty(SystemProperties.SECURITY_ENCRYPTOR_USE_STRONG_RANDOM_NUMBER_GENERATOR);
if (useStrongRNG == null || useStrongRNG.equalsIgnoreCase("false")) {
random = new SecureRandom();
} else if (useStrongRNG.equalsIgnoreCase("true")) {
try {
random = SecureRandom.getInstanceStrong();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
} else {
throw ValidationException.invalidBooleanValueForProperty(useStrongRNG, SystemProperties.SECURITY_ENCRYPTOR_USE_STRONG_RANDOM_NUMBER_GENERATOR);
}
random.nextBytes(ivGCM);
return ivGCM;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024 Contributors to the Eclipse Foundation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -50,13 +51,13 @@
/**
* INTERNAL:
* Privileged Access Helper provides a utility so all calls that require privileged access can use the same code.
*
* <p>
* Do privileged blocks can be used with a security manager to grant a code base (eclipselink.jar) access to certain
* Java operations such as reflection. Generally a security manager is not enabled in a JVM, so this is not an issue.
* If a security manager is enabled, then either the application can be configured to have access to operations such as
* reflection, or only EclipseLink can be given access. If only EclipseLink is desired to be given access then
* do privileged must be enabled through the System property "eclipselink.security.usedoprivileged"=true.
*
* <p>
* Note the usage of do privileged has major impacts on performance, so should normally be avoided.
*/
public class PrivilegedAccessHelper {
Expand All @@ -75,6 +76,7 @@ public class PrivilegedAccessHelper {
SystemProperties.CONCURRENCY_MANAGER_ACQUIRE_WAIT_TIME, SystemProperties.CONCURRENCY_MANAGER_BUILD_OBJECT_COMPLETE_WAIT_TIME, SystemProperties.CONCURRENCY_MANAGER_MAX_SLEEP_TIME,
SystemProperties.CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_TINY_MESSAGE, SystemProperties.CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_MASSIVE_MESSAGE,
SystemProperties.CONCURRENCY_MANAGER_ALLOW_INTERRUPTED_EXCEPTION, SystemProperties.CONCURRENCY_MANAGER_ALLOW_CONCURRENCY_EXCEPTION, SystemProperties.CONCURRENCY_MANAGER_ALLOW_STACK_TRACE_READ_LOCK,
SystemProperties.SECURITY_ENCRYPTOR_USE_STRONG_RANDOM_NUMBER_GENERATOR,
ServerPlatformBase.JMX_REGISTER_RUN_MBEAN_PROPERTY, ServerPlatformBase.JMX_REGISTER_DEV_MBEAN_PROPERTY,
XMLPlatformFactory.XML_PLATFORM_PROPERTY};
private final static Set<String> legalPropertiesSet = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(legalProperties)));
Expand Down

0 comments on commit a96b873

Please sign in to comment.