eclipse-vertx / vertx-auth

Apache License 2.0
160 stars 153 forks source link

Usage of PRNG can lead to blocking of thread #666

Closed st-h closed 10 months ago

st-h commented 10 months ago

I have been noticing issues with blocked threads for a while on running vertx instances. I have been finally looking into this and came across this article: https://tersesystems.com/blog/2015/12/17/the-right-way-to-use-securerandom/

Turns out that are two resources for getting random numbers on OS level: /dev/urandom (which might block) and /dev/urandom (which shall not block).

I am seeing the following Stacktrace:

io.vertx.core.VertxException: Thread blocked
  java.io.FileInputStream.readBytes (FileInputStream.java:-2)
  java.io.FileInputStream.read (FileInputStream.java:279)
  java.io.FilterInputStream.read (FilterInputStream.java:133)
  sun.security.provider.NativePRNG$RandomIO.readFully (NativePRNG.java:424)
  sun.security.provider.NativePRNG$RandomIO.implGenerateSeed (NativePRNG.java:441)
  sun.security.provider.NativePRNG.engineGenerateSeed (NativePRNG.java:226)
  java.security.SecureRandom.generateSeed (SecureRandom.java:857)
  io.vertx.ext.auth.PRNG.lambda$null$0 (PRNG.java:80)
  io.vertx.ext.auth.PRNG$$Lambda$2203/0x0000000800bf5040.handle ([unknown]:-1)
  io.vertx.core.impl.ContextBase.lambda$null$0 (ContextBase.java:137)
  io.vertx.core.impl.ContextBase$$Lambda$288/0x00000008003abc40.handle ([unknown]:-1)
  io.vertx.core.impl.ContextInternal.dispatch (ContextInternal.java:264)
  io.vertx.core.impl.ContextBase.lambda$executeBlocking$1 (ContextBase.java:135)
  io.vertx.core.impl.ContextBase$$Lambda$283/0x00000008003a9840.run ([unknown]:-1)
  java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1128)
  java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:628)
  io.netty.util.concurrent.FastThreadLocalRunnable.run (FastThreadLocalRunnable.java:30)
  java.lang.Thread.run (Thread.java:829)

Please note, there is no reference to my own code here.

The article explains that generateSeed uses the blocking way, whereas the non blocking alternative would be the nextBytes method.

Similar information can be found in the oracle docs https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SUNProvider : NativePRNG (nextBytes() uses /dev/urandom, generateSeed() uses /dev/random)

I am wondering, if generateSeed has been used intentionally and if there is a different cause for my blocking issue, or if this indeed is a bug?

pmlopes commented 10 months ago

This was intentional as the 2 methos have distinct objectives. The seeding part (which can block) is running inside a execute blocking call. The exception can still be thrown, but means that your system is out of introphy. I suggest you to install the rng-tools package in your linux distro that provides the daemon rngd.

https://manpages.debian.org/unstable/rng-tools-debian/rngd.8.en.html

tsegismont commented 10 months ago

@st-h you the Vert.x blocked thread checker does not check only event loops threads, but worker pool threads as well. So this warning is not an indication of blocked event loops

st-h commented 10 months ago

Ah, thanks a lot for the explanation. I'll look into the rngd daemon.