Skip to content

Commit a96b873

Browse files
authored
Fix #2075 Slow startup because of low entropy for PRNG (#2318) (#2335)
* Fix hang-up due to blocking PRNG returned by SecureRandom.getInstanceStrong() Fixes #2075 (cherry picked from commit 4ef3517) Signed-off-by: Zuplyx <[email protected]>
1 parent 452ffdd commit a96b873

File tree

3 files changed

+59
-34
lines changed

3 files changed

+59
-34
lines changed

foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/config/SystemProperties.java

+41-27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2024 Contributors to the Eclipse Foundation. All rights reserved.
34
*
45
* This program and the accompanying materials are made available under the
56
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -75,7 +76,7 @@ public class SystemProperties {
7576

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

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

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

105106
/**
106107
* This system property in milliseconds can control thread management in org.eclipse.persistence.internal.helper.ConcurrencyManager.
107-
* 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
108+
* 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
108109
* mechanism and related extended logging will be activated.
109110
* Default value is 0 (unit is ms). Allowed values are: long
110111
*/
111112
public static final String CONCURRENCY_MANAGER_ACQUIRE_WAIT_TIME = "eclipselink.concurrency.manager.waittime";
112113

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

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

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

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

142143
/**
143144
* <p>
144-
* This property control (enable/disable) if <code>InterruptedException</code> fired when dead-lock diagnostic is enabled.
145+
* This property control (enable/disable) if {@code InterruptedException} fired when dead-lock diagnostic is enabled.
145146
* <p>
146147
* <b>Allowed Values</b> (case sensitive String)<b>:</b>
147148
* <ul>
148-
* <li>"<code>false</code>" - if aborting frozen thread is not effective it is preferable to not fire the interrupted exception let the system
149+
* <li>"{@code false}" - if aborting frozen thread is not effective it is preferable to not fire the interrupted exception let the system
149150
* In the places where use this property normally if a thread is stuck it is because it is doing object building.
150151
* Blowing the threads ups is not that dangerous. It can be very dangerous for production if the dead lock ends up
151152
* not being resolved because the productive business transactions will become cancelled if the application has a
152153
* limited number of retries to for example process an MDB. However, the code spots where we use this constant are
153154
* not as sensible as when the write lock manager is starving to run commit.
154-
* <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
155+
* <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
155156
* threads to progress.
156157
* </ul>
157158
*/
158159
public static final String CONCURRENCY_MANAGER_ALLOW_INTERRUPTED_EXCEPTION = "eclipselink.concurrency.manager.allow.interruptedexception";
159160

160161
/**
161162
* <p>
162-
* This property control (enable/disable) if <code>ConcurrencyException</code> fired when dead-lock diagnostic is enabled.
163+
* This property control (enable/disable) if {@code ConcurrencyException} fired when dead-lock diagnostic is enabled.
163164
* <p>
164165
* <b>Allowed Values</b> (case sensitive String)<b>:</b>
165166
* <ul>
166-
* <li>"<code>false</code>" - if aborting frozen thread is not effective it is preferable to not fire the concurrency exception let the system
167+
* <li>"{@code false}" - if aborting frozen thread is not effective it is preferable to not fire the concurrency exception let the system
167168
* freeze and die and force the administration to kill the server. This is preferable to aborting the transactions
168169
* multiple times without success in resolving the dead lock and having business critical messages that after 3 JMS
169170
* retries are discarded out. Failing to resolve a dead lock can have terrible impact in system recovery unless we
170171
* have infinite retries for the business transactions.
171-
* <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
172+
* <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
172173
* locks and allow other threads to progress.
173174
* </ul>
174175
*/
@@ -180,8 +181,8 @@ public class SystemProperties {
180181
* <p>
181182
* <b>Allowed Values</b> (case sensitive String)<b>:</b>
182183
* <ul>
183-
* <li>"<code>false</code>" (DEFAULT) - don't collect debug/trace information during ReadLock acquisition
184-
* <li>"<code>true</code>" - collect debug/trace information during ReadLock acquisition. Has negative impact to the performance.
184+
* <li>"{@code false}" (DEFAULT) - don't collect debug/trace information during ReadLock acquisition
185+
* <li>"{@code true}" - collect debug/trace information during ReadLock acquisition. Has negative impact to the performance.
185186
* </ul>
186187
*/
187188
public static final String CONCURRENCY_MANAGER_ALLOW_STACK_TRACE_READ_LOCK = "eclipselink.concurrency.manager.allow.readlockstacktrace";
@@ -192,13 +193,13 @@ public class SystemProperties {
192193
* </p>
193194
* Object building see {@link org.eclipse.persistence.internal.descriptors.ObjectBuilder} could be one of the
194195
* primary sources pressure on concurrency manager. Most of the cache key acquisition and releasing is taking place during object building.
195-
* Enable <code>true</code> this property to try reduce the likelihood of having dead locks is to allow less threads to start object
196+
* Enable {@code true} this property to try reduce the likelihood of having dead locks is to allow less threads to start object
196197
* building in parallel. In this case there should be negative impact to the performance.
197198
* Note: Parallel access to the same entity/entity tree from different threads is not recommended technique in EclipseLink.
198199
* <ul>
199-
* <li>"<code>true</code>" - means we want to override vanilla behavior and use a semaphore to not allow too many
200+
* <li>"{@code true}" - means we want to override vanilla behavior and use a semaphore to not allow too many
200201
* threads in parallel to do object building
201-
* <li>"<code>false</code>" (DEFAULT) - means just go ahead and try to build the object without any semaphore (false is
202+
* <li>"{@code false}" (DEFAULT) - means just go ahead and try to build the object without any semaphore (false is
202203
* vanilla behavior).
203204
* </ul>
204205
*/
@@ -215,9 +216,9 @@ public class SystemProperties {
215216
* one-to-many relations of master detail being enriched with more details on this master).
216217
* Note: Parallel access to the same entity/entity tree from different threads is not recommended technique in EclipseLink.
217218
* <ul>
218-
* <li>"<code>true</code>" - means we want to override vanilla behavior and use a semaphore to not allow too many
219+
* <li>"{@code true}" - means we want to override vanilla behavior and use a semaphore to not allow too many
219220
* threads. In this case there should be negative impact to the performance.
220-
* <li>"<code>false</code>" (DEFAULT) - means just go ahead and try to build the object without any semaphore (false is
221+
* <li>"{@code false}" (DEFAULT) - means just go ahead and try to build the object without any semaphore (false is
221222
* vanilla behavior).
222223
* </ul>
223224
*/
@@ -226,17 +227,17 @@ public class SystemProperties {
226227
/**
227228
* <p>
228229
* This property control number of threads in semaphore in {@link org.eclipse.persistence.internal.descriptors.ObjectBuilder}
229-
* If "eclipselink.concurrency.manager.object.building.semaphore" property is <code>true</code> default value is 10. Allowed values are: int
230-
* If "eclipselink.concurrency.manager.object.building.semaphore" property is <code>false</code> (DEFAULT) number of threads is unlimited.
230+
* If "eclipselink.concurrency.manager.object.building.semaphore" property is {@code true} default value is 10. Allowed values are: int
231+
* If "eclipselink.concurrency.manager.object.building.semaphore" property is {@code false} (DEFAULT) number of threads is unlimited.
231232
* </p>
232233
*/
233234
public static final String CONCURRENCY_MANAGER_OBJECT_BUILDING_NO_THREADS = "eclipselink.concurrency.manager.object.building.no.threads";
234235

235236
/**
236237
* <p>
237238
* This property control number of threads in semaphore in {@link org.eclipse.persistence.internal.helper.WriteLockManager#acquireRequiredLocks}
238-
* If "eclipselink.concurrency.manager.write.lock.manager.semaphore" property is <code>true</code> default value is 2. Allowed values are: int
239-
* If "eclipselink.concurrency.manager.write.lock.manager.semaphore" property is <code>false</code> (DEFAULT) number of threads is unlimited.
239+
* If "eclipselink.concurrency.manager.write.lock.manager.semaphore" property is {@code true} default value is 2. Allowed values are: int
240+
* If "eclipselink.concurrency.manager.write.lock.manager.semaphore" property is {@code false} (DEFAULT) number of threads is unlimited.
240241
* </p>
241242
*/
242243
public static final String CONCURRENCY_MANAGER_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS_NO_THREADS = "eclipselink.concurrency.manager.write.lock.manager.no.threads";
@@ -265,12 +266,25 @@ public class SystemProperties {
265266
* <p>
266267
* <b>Allowed Values</b> (case sensitive String)<b>:</b>
267268
* <ul>
268-
* <li>"<code>eclipselink</code>" (DEFAULT) - use ASM implementation from <i>org.eclipse.persistence.asm</i> project.</li>
269-
* <li>"<code>ow2</code>" - use ASM implementation from <i>org.ow2.asm</i> project.</li>
269+
* <li>"{@code eclipselink}" (DEFAULT) - use ASM implementation from <i>org.eclipse.persistence.asm</i> project.</li>
270+
* <li>"{@code ow2}" - use ASM implementation from <i>org.ow2.asm</i> project.</li>
270271
* </ul>
271272
*/
272273
public static final String ASM_SERVICE = "eclipselink.asm.service";
273274

275+
/**
276+
* <p>
277+
* This property controls the random number generator (RNG) used for password encryption.
278+
* <p>
279+
* <b>Allowed Values</b> (case sensitive String)<b>:</b>
280+
* <ul>
281+
* <li>"{@code false}" (DEFAULT) - use default RNG of Java platform
282+
* <li>"{@code true}" - use RNG indicated by the securerandom.strongAlgorithms security property of Java platform
283+
* </ul>
284+
*/
285+
public static final String SECURITY_ENCRYPTOR_USE_STRONG_RANDOM_NUMBER_GENERATOR = "eclipselink.security.encryptor.use.strong.random.number.generator";
286+
287+
274288
/**
275289
* @deprecated This constructor will be marked private and the class final. It is not designed for extensibility.
276290
*/

foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/security/JCEEncryptor.java

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2024 Contributors to the Eclipse Foundation. All rights reserved.
34
*
45
* This program and the accompanying materials are made available under the
56
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -14,6 +15,7 @@
1415
// Oracle - initial API and implementation from Oracle TopLink
1516
package org.eclipse.persistence.internal.security;
1617

18+
import org.eclipse.persistence.config.SystemProperties;
1719
import org.eclipse.persistence.exceptions.ConversionException;
1820
import org.eclipse.persistence.exceptions.ValidationException;
1921
import org.eclipse.persistence.internal.helper.Helper;
@@ -124,10 +126,17 @@ private static SecretKey getAESGCMMultitasker() throws Exception {
124126
private static byte[] getIvGCM() {
125127
byte[] ivGCM = new byte[IV_GCM_LENGTH];
126128
SecureRandom random = null;
127-
try {
128-
random = SecureRandom.getInstanceStrong();
129-
} catch (NoSuchAlgorithmException e) {
130-
throw new RuntimeException(e);
129+
String useStrongRNG = PrivilegedAccessHelper.getSystemProperty(SystemProperties.SECURITY_ENCRYPTOR_USE_STRONG_RANDOM_NUMBER_GENERATOR);
130+
if (useStrongRNG == null || useStrongRNG.equalsIgnoreCase("false")) {
131+
random = new SecureRandom();
132+
} else if (useStrongRNG.equalsIgnoreCase("true")) {
133+
try {
134+
random = SecureRandom.getInstanceStrong();
135+
} catch (NoSuchAlgorithmException e) {
136+
throw new RuntimeException(e);
137+
}
138+
} else {
139+
throw ValidationException.invalidBooleanValueForProperty(useStrongRNG, SystemProperties.SECURITY_ENCRYPTOR_USE_STRONG_RANDOM_NUMBER_GENERATOR);
131140
}
132141
random.nextBytes(ivGCM);
133142
return ivGCM;

foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/security/PrivilegedAccessHelper.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
2-
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2024 Contributors to the Eclipse Foundation. All rights reserved.
34
*
45
* This program and the accompanying materials are made available under the
56
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -50,13 +51,13 @@
5051
/**
5152
* INTERNAL:
5253
* Privileged Access Helper provides a utility so all calls that require privileged access can use the same code.
53-
*
54+
* <p>
5455
* Do privileged blocks can be used with a security manager to grant a code base (eclipselink.jar) access to certain
5556
* Java operations such as reflection. Generally a security manager is not enabled in a JVM, so this is not an issue.
5657
* If a security manager is enabled, then either the application can be configured to have access to operations such as
5758
* reflection, or only EclipseLink can be given access. If only EclipseLink is desired to be given access then
5859
* do privileged must be enabled through the System property "eclipselink.security.usedoprivileged"=true.
59-
*
60+
* <p>
6061
* Note the usage of do privileged has major impacts on performance, so should normally be avoided.
6162
*/
6263
public class PrivilegedAccessHelper {
@@ -75,6 +76,7 @@ public class PrivilegedAccessHelper {
7576
SystemProperties.CONCURRENCY_MANAGER_ACQUIRE_WAIT_TIME, SystemProperties.CONCURRENCY_MANAGER_BUILD_OBJECT_COMPLETE_WAIT_TIME, SystemProperties.CONCURRENCY_MANAGER_MAX_SLEEP_TIME,
7677
SystemProperties.CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_TINY_MESSAGE, SystemProperties.CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_MASSIVE_MESSAGE,
7778
SystemProperties.CONCURRENCY_MANAGER_ALLOW_INTERRUPTED_EXCEPTION, SystemProperties.CONCURRENCY_MANAGER_ALLOW_CONCURRENCY_EXCEPTION, SystemProperties.CONCURRENCY_MANAGER_ALLOW_STACK_TRACE_READ_LOCK,
79+
SystemProperties.SECURITY_ENCRYPTOR_USE_STRONG_RANDOM_NUMBER_GENERATOR,
7880
ServerPlatformBase.JMX_REGISTER_RUN_MBEAN_PROPERTY, ServerPlatformBase.JMX_REGISTER_DEV_MBEAN_PROPERTY,
7981
XMLPlatformFactory.XML_PLATFORM_PROPERTY};
8082
private final static Set<String> legalPropertiesSet = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(legalProperties)));

0 commit comments

Comments
 (0)