[graalvm-dev] Random seed baked in the Native image on Windows

Michal Karm michal.babacek at gmail.com
Thu Apr 16 04:10:43 PDT 2020


Hello,

I have been getting acquainted with GraalVM and I picked Issue 2265 [1] as the
thing to look at. Both Windows and Linux examples below use master-ish fresh
build of Graal's substratevm and compiler with LabsJDK 11.

e.g. program like this:


    import java.security.SecureRandom;
    import java.util.UUID;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
   
    public class Main {
        public static void main(String[] args) {
            System.out.println("Hello, UUID: " + UUID.randomUUID().toString());
            IntStream intStream = new SecureRandom().ints(10, 0, 100);
            System.out.println("Hello, secureRandom: " +
intStream.boxed().collect(Collectors.toList()));
        }
    }


works correctly when used on Linux. See:

Linux:

    export
GRAALVM_HOME=/home/karm/workspace/graal/graal/sdk/mxbuild/linux-amd64/GRAALVM_865E91DFC2_JAVA11/graalvm-865e91dfc2-java11-20.1.0-dev/
    export PATH=${GRAALVM_HOME}/bin:${PATH}
   
    $ javac Main.java && native-image -H:+ReportExceptionStackTraces
-H:+TraceClassInitialization -H:+PrintClassInitialization Main
   
    $ ./main
    Hello, UUID: da5c0a01-bd99-486d-83e7-b2561b4c2384
    Hello, secureRandom: [33, 55, 58, 49, 59, 39, 91, 38, 4, 43]
   
    $ ./main
    Hello, UUID: 32c7621f-fda5-485c-b797-d10e1d8ea5df
    Hello, secureRandom: [72, 38, 24, 17, 94, 61, 1, 68, 74, 6]


I can see with strace that the source of entropy file is accessed
and everything is fine. The engine is seeded and the sequence is different for
each execution of the native image binary:

Linux strace:

    lstat("/dev/urandom", {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 9), ...}) = 0
    open("/dev/urandom", O_RDONLY)          = 4
    fstat(4, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 9), ...}) = 0
    read(4, "\377\6\177\242\355\237\315\23\332P\6S\225\0252\225D\7l\255", 20) = 20
    read(4,
"\321\344H!OJ\240)H\317\3542^}\204\341\325\321\215\367q\370+\364m5\240\324E\361\331V"...,
256) = 256

The Windows story is different though, first see the execution:


Windows:

    λ set
JAVA_HOME=C:\Users\Administrator\source\graal\sdk\mxbuild\windows-amd64\GRAALVM_UNKNOWN_JAVA11\graalvm-unknown-java11-20.1.0-dev\
    λ set
GRAALVM_HOME=C:\Users\Administrator\source\graal\sdk\mxbuild\windows-amd64\GRAALVM_UNKNOWN_JAVA11\graalvm-unknown-java11-20.1.0-dev\
    λ set PATH=%GRAALVM_HOME%\bin;%PATH%
    λ vcvars64.bat
   
   
    λ javac Main.java && native-image -H:+ReportExceptionStackTraces
-H:+TraceClassInitialization -H:+PrintClassInitialization Main
    [main:5264]    classlist:   2,151.28 ms,  1.20 GB
    [main:5264]        (cap):   2,207.03 ms,  1.20 GB
    [main:5264]        setup:   4,060.94 ms,  1.20 GB
    Printing initializer configuration to
C:\Users\Administrator\source\UUID\src\com\company\reports\initializer_configuration_20200415_082240.txt
    [main:5264]   (typeflow):   9,626.26 ms,  1.77 GB
    [main:5264]    (objects):   6,881.04 ms,  1.77 GB
    [main:5264]   (features):     515.65 ms,  1.77 GB
    [main:5264]     analysis:  17,506.36 ms,  1.77 GB
    Printing initializer dependencies to
C:\Users\Administrator\source\UUID\src\com\company\reports\initializer_dependencies_20200415_082258.dot
    Printing 1 classes that are considered as safe for build-time initialization to
   
C:\Users\Administrator\source\UUID\src\com\company\reports\safe_classes_20200415_082259.txt
    Printing 3404 classes of type BUILD_TIME to
C:\Users\Administrator\source\UUID\src\com\company\reports\build_time_classes_20200415_082259.txt
    Printing 53 classes of type RERUN to
C:\Users\Administrator\source\UUID\src\com\company\reports\rerun_classes_20200415_082259.txt
    Printing 0 classes of type RUN_TIME to
C:\Users\Administrator\source\UUID\src\com\company\reports\run_time_classes_20200415_082259.txt
    [main:5264]     (clinit):     348.44 ms,  1.77 GB
    [main:5264]     universe:     849.06 ms,  1.77 GB
    [main:5264]      (parse):   2,403.52 ms,  1.77 GB
    [main:5264]     (inline):   1,569.22 ms,  1.77 GB
    [main:5264]    (compile):  14,694.79 ms,  2.05 GB
    [main:5264]      compile:  19,411.07 ms,  2.05 GB
    [main:5264]        image:   1,400.01 ms,  2.05 GB
    [main:5264]        write:     687.18 ms,  2.05 GB
    [main:5264]      [total]:  46,486.99 ms,  2.05 GB



    C:\Users\Administrator\source\UUID\src\com\company
    λ main
    Hello, UUID: 796b49e2-4c67-4dba-bbca-93bcca89adcc
    Hello, secureRandom: [30, 96, 71, 90, 57, 97, 76, 72, 83, 83]
   
   
    C:\Users\Administrator\source\UUID\src\com\company
    λ main
    Hello, UUID: 796b49e2-4c67-4dba-bbca-93bcca89adcc
    Hello, secureRandom: [30, 96, 71, 90, 57, 97, 76, 72, 83, 83]


As you can see, the engine is not reseeded on initialization at runtime,
the seed is the same, baked in the image, the sequence is the same.
I would like to change that :-)


Unlike Linux, Windows does not use a file to offer entropy, but there is an
API for that [2, security.cpp], leveraged from PRNG.java via JNI [3, PRNG.java].


So I wondered whether the seed here is not baked in the image, see [4, Random.java].


Is there anything I could try to do here, see [5, SecurityServicesFeature.java] ?
I tried to poke around without any success so far, but I am new to Graal, so it
might
be obvious what to do to some of you...

I also tried to fiddle with --initialize-at-run-time=, but it didn't get me far
"Error: The class java.util.Random has already been initialized".

Apart from toying with [5, SecurityServicesFeature.java], how about things like
Substitutions and Aliases, e.g.

    @TargetClass(className = "java.util.Random")
    final class Target_java_util_Random {
        @Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset,
isFinal = true)//
        private AtomicLong seed;
    }

I used also Kind.FromAlias with experiments such as ```private AtomicLong seed =
new AtomicLong(System.nanoTime());```
and to my surprise, an attempt at Kind.NewInstance throws substratevm build into
a halt during nativeimage.exe
build where the build server keeps consuming all CPU it can get and it goes
nowhere. There seems to be no timeout
and no error message.

What I would appreciate immensely:

I am not looking for a fix for that bug [1] per se. I am looking for
understanding of what goes on and what are the
tools to try and to tackle such a problem.

If anyone could take the time to explain what are the mechanisms in [5,
SecurityServicesFeature.java] meant to achieve
and how may I exploit them to address the issue and how substitutions and
aliases could be of help, it would be great.

I also gladly accept a brutal Reddit style downvote with "OMG, all these things
are for BUILD time tweaks
and what you need is to EXCLUDE the seed from BUILD time altogether..." :-)


Thank you for your time and patience and see you on github.com/oracle/graal

Best regards

Karm




[1] https://github.com/oracle/graal/issues/2265
[2, security.cpp]
https://github.com/graalvm/labs-openjdk-11/blob/master/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp#L243:L357
[3, PRNG.java]
https://github.com/graalvm/labs-openjdk-11/blob/master/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/PRNG.java#L46
[4, Random.java]
https://github.com/graalvm/labs-openjdk-11/blob/master/src/java.base/share/classes/java/util/Random.java#L86
[5, SecurityServicesFeature.java]
https://github.com/oracle/graal/blob/master/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java#L98:L111


Michal Karm Babacek

-- 
Sent from my Hosaka Ono-Sendai Cyberspace 7

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
Url : http://oss.oracle.com/pipermail/graalvm-dev/attachments/20200416/6664727b/attachment.bin 


More information about the GraalVM-Dev mailing list