Skip to content

build: stop CI switching the default SecureRandom away from NativePRNG - #3482

Open
pjfanning wants to merge 1 commit into
apache:mainfrom
pjfanning:ci-egd-urandom
Open

build: stop CI switching the default SecureRandom away from NativePRNG#3482
pjfanning wants to merge 1 commit into
apache:mainfrom
pjfanning:ci-egd-urandom

Conversation

@pjfanning

Copy link
Copy Markdown
Member

Motivation

The build and every CI workflow pass -Djava.security.egd=file:/dev/./urandom. The /./ is a long-standing workaround whose only effect today is to stop the string matching SunEntries.URL_DEV_URANDOM:

DEF_SECURE_RANDOM_ALGO = (NativePRNG.isAvailable() &&
    (seedSource.equals(URL_DEV_URANDOM) || seedSource.equals(URL_DEV_RANDOM))
    ? "NativePRNG" : "DRBG");

So CI resolves new SecureRandom to something other than the algorithm users get. Measured on every JDK in the build matrix:

JDK unset file:/dev/./urandom file:/dev/urandom
8 NativePRNG SHA1PRNG NativePRNG
11 NativePRNG DRBG NativePRNG
17 NativePRNG DRBG NativePRNG
21 NativePRNG DRBG NativePRNG
25 NativePRNG DRBG NativePRNG

On the 1.x nightlies (javaVersion: [8, 11, 17, 21]) that means the JDK 8 jobs have been defaulting to SHA1PRNG — which seeds once at startup and never reseeds.

This reaches production code, not just the launcher: SecureRandomFactory maps random-number-generator = "" straight to new SecureRandom, so TlsTcpSpec, Ticket1978CommunicationSpec and friends have not been exercising the algorithm users actually run with.

The workaround is also no longer needed for its original purpose. On Unix, NativeSeedGenerator extends SeedGenerator.URLSeedGenerator and passes the seed file through unchanged — verified in both the JDK 8 and JDK 21 sources — so file:/dev/urandom reads /dev/urandom and does not block on any supported JDK. The special case only diverges on Windows.

Modification

Use file:/dev/urandom in project/PekkoBuild.scala, .jvmopts-ci and the twelve workflow files.

Record why the plain path matters next to the two definitions that are hand-edited, so the /./ is not reintroduced by someone recognising the old idiom.

Result

CI seeds from a non-blocking source, exactly as before, and new SecureRandom resolves to NativePRNG on every JDK in the matrix — matching an unconfigured JVM, which is what users get.

No change to shipped defaults, to reference.conf, or to any published artifact. Build and CI configuration only.

Tests

  • scalafmt project/PekkoBuild.scala — reformatted, no further changes
  • Measured the table above by running new SecureRandom().getAlgorithm() under each flag on Temurin 8.0.492, 11.0.31, 17.0.19, 21.0.11 and 25.0.3
  • No directional test: this is build/CI configuration with no runtime code path of its own

References

Refs #3481

Motivation:
The build and every CI workflow pass -Djava.security.egd=file:/dev/./urandom.
The `/./` is a long-standing workaround whose only effect today is to stop the
string matching SunEntries.URL_DEV_URANDOM:

  DEF_SECURE_RANDOM_ALGO = (NativePRNG.isAvailable() &&
      (seedSource.equals(URL_DEV_URANDOM) || seedSource.equals(URL_DEV_RANDOM))
      ? "NativePRNG" : "DRBG");

So CI resolves `new SecureRandom` to something other than the algorithm users
get. Measured on every JDK in the build matrix:

  JDK   unset        file:/dev/./urandom   file:/dev/urandom
  8     NativePRNG   SHA1PRNG              NativePRNG
  11    NativePRNG   DRBG                  NativePRNG
  17    NativePRNG   DRBG                  NativePRNG
  21    NativePRNG   DRBG                  NativePRNG
  25    NativePRNG   DRBG                  NativePRNG

On the 1.x nightlies that means JDK 8 jobs have been defaulting to SHA1PRNG,
which seeds once at startup and never reseeds. This reaches production code:
SecureRandomFactory maps `random-number-generator = ""` straight to
`new SecureRandom`, so the TLS specs have not been exercising what users run.

The workaround is also no longer needed for its original purpose. On Unix
NativeSeedGenerator extends SeedGenerator.URLSeedGenerator and passes the seed
file through unchanged - verified in the JDK 8 and JDK 21 sources - so
`file:/dev/urandom` reads /dev/urandom and does not block on any supported JDK.
The special case only diverges on Windows.

Modification:
Use `file:/dev/urandom` in PekkoBuild.scala, .jvmopts-ci and the twelve
workflow files. Record why the plain path matters next to the two definitions
that are hand-edited, so the `/./` is not reintroduced.

Result:
CI seeds from a non-blocking source, as before, and `new SecureRandom` resolves
to NativePRNG on every JDK in the matrix, matching an unconfigured JVM. No
change to shipped defaults or to any published artifact.

Tests:
- scalafmt project/PekkoBuild.scala - reformatted, no further changes
- Measured the table above by running `new SecureRandom().getAlgorithm()` under
  each flag on Temurin 8.0.492, 11.0.31, 17.0.19, 21.0.11 and 25.0.3

References:
Refs apache#3481
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants