-
Bug
-
Resolution: Won't Fix
-
P4
-
10.0.2, 11, 12
-
x86_64
-
linux
ADDITIONAL SYSTEM INFORMATION :
Debian Linux 4.1.35; jdk 10.0.2
A DESCRIPTION OF THE PROBLEM :
Java 9 added the ability to pass command line options in an argument, or options file, specified with an '@' on the command line. This is a very valuable feature, especially if you want to pass long command line arguments. Crucially, it allows users to bypass the Linux kernel's limit on the length of arguments.
The java launcher also has a feature to validate the LD_LIBRARY_PATH envvar. If it find a lib/{client,server}/libjvm.so anywhere on the LD_LIBRARY_PATH, other than the first entry, the launcher modifies LD_LIBRARY_PATH and calls execve to recursively reinvoke itself. (See http://hg.openjdk.java.net/jdk/jdk10/file/b09e56145e11/src/java.base/unix/native/libjli/java_md_solinux.c)
Unfortunately, this happens _after_ arguments have been read from the argument file. When the launcher calls execve, it passes in the expanded argument list. If these arguments are too long, the call to execve fails, and java fails to start, after reporting an error message.
I believe this check should happen _before_ the argument file is expanded. Then execve will be called with the original, unexpanded arguments, and ought to succeed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
# create a 1MB option in a file
echo "-Dfoo=$(cat /dev/urandom | tr -cd '[:alpha:]' | head -c 1000000)" > /tmp/jvm_options
LD_LIBRARY_PATH=".:${JAVA_HOME}/lib/server" "${JAVA_HOME}/java @/tmp/jvm_options Foo
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
#The JVM should start up, and report than Foo can't be found:
Error: Could not find or load main class Foo
Caused by: java.lang.ClassNotFoundException: Foo
ACTUAL -
#The JVM fails to start:
Argument list too long
Error: trying to exec .../bin/java.
Check if file exists and permissions are set correctly.
CUSTOMER SUBMITTED WORKAROUND :
Don't set LD_LIBRARY_PATH, or ensure that the JRE's server/lib directory always appears as the first entry in the path.
FREQUENCY : always
Debian Linux 4.1.35; jdk 10.0.2
A DESCRIPTION OF THE PROBLEM :
Java 9 added the ability to pass command line options in an argument, or options file, specified with an '@' on the command line. This is a very valuable feature, especially if you want to pass long command line arguments. Crucially, it allows users to bypass the Linux kernel's limit on the length of arguments.
The java launcher also has a feature to validate the LD_LIBRARY_PATH envvar. If it find a lib/{client,server}/libjvm.so anywhere on the LD_LIBRARY_PATH, other than the first entry, the launcher modifies LD_LIBRARY_PATH and calls execve to recursively reinvoke itself. (See http://hg.openjdk.java.net/jdk/jdk10/file/b09e56145e11/src/java.base/unix/native/libjli/java_md_solinux.c)
Unfortunately, this happens _after_ arguments have been read from the argument file. When the launcher calls execve, it passes in the expanded argument list. If these arguments are too long, the call to execve fails, and java fails to start, after reporting an error message.
I believe this check should happen _before_ the argument file is expanded. Then execve will be called with the original, unexpanded arguments, and ought to succeed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
# create a 1MB option in a file
echo "-Dfoo=$(cat /dev/urandom | tr -cd '[:alpha:]' | head -c 1000000)" > /tmp/jvm_options
LD_LIBRARY_PATH=".:${JAVA_HOME}/lib/server" "${JAVA_HOME}/java @/tmp/jvm_options Foo
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
#The JVM should start up, and report than Foo can't be found:
Error: Could not find or load main class Foo
Caused by: java.lang.ClassNotFoundException: Foo
ACTUAL -
#The JVM fails to start:
Argument list too long
Error: trying to exec .../bin/java.
Check if file exists and permissions are set correctly.
CUSTOMER SUBMITTED WORKAROUND :
Don't set LD_LIBRARY_PATH, or ensure that the JRE's server/lib directory always appears as the first entry in the path.
FREQUENCY : always