6733959: Insufficient checks for "Main-Class" manifest entry in JAR files
Fixes a buffer overrun problem with a very long Main-Class attribute. Reviewed-by: darcy
This commit is contained in:
parent
6aab63dd37
commit
3a7a9cc557
@ -54,6 +54,7 @@
|
||||
#define CLS_ERROR2 "Error: Failed to load Main Class: %s\n%s"
|
||||
#define CLS_ERROR3 "Error: No main method found in specified class.\n" GEN_ERROR
|
||||
#define CLS_ERROR4 "Error: Main method not public\n" GEN_ERROR
|
||||
#define CLS_ERROR5 "Error: main-class: attribute exceeds system limits of %d bytes\n" GEN_ERROR
|
||||
|
||||
#define CFG_WARN1 "Warning: %s VM not supported; %s VM will be used"
|
||||
#define CFG_WARN2 "Warning: No leading - on line %d of `%s'"
|
||||
|
@ -987,8 +987,14 @@ SelectVersion(int argc, char **argv, char **main_class)
|
||||
* to avoid locating, expanding and parsing the manifest extra
|
||||
* times.
|
||||
*/
|
||||
if (info.main_class != NULL)
|
||||
(void)JLI_StrCat(env_entry, info.main_class);
|
||||
if (info.main_class != NULL) {
|
||||
if (JLI_StrLen(info.main_class) <= MAXNAMELEN) {
|
||||
(void)JLI_StrCat(env_entry, info.main_class);
|
||||
} else {
|
||||
ReportErrorMessage(CLS_ERROR5, MAXNAMELEN);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
(void)putenv(env_entry);
|
||||
ExecJRE(jre, new_argv);
|
||||
JLI_FreeManifest();
|
||||
|
@ -1,14 +1,14 @@
|
||||
# @test MultipleJRE.sh
|
||||
# @bug 4811102 4953711 4955505 4956301 4991229 4998210 5018605 6387069
|
||||
# @bug 4811102 4953711 4955505 4956301 4991229 4998210 5018605 6387069 6733959
|
||||
# @build PrintVersion
|
||||
# @build UglyPrintVersion
|
||||
# @build ZipMeUp
|
||||
# @run shell MultipleJRE.sh
|
||||
# @summary Verify Multiple JRE version support
|
||||
# @author Joseph E. Kowalski
|
||||
|
||||
|
||||
#
|
||||
# Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -49,10 +49,25 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JAVAEXE="$TESTJAVA/bin/java"
|
||||
JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES"
|
||||
JAR="$TESTJAVA/bin/jar"
|
||||
OS=`uname -s`;
|
||||
|
||||
#
|
||||
# Tests whether we are on windows (true) or not.
|
||||
#
|
||||
IsWindows() {
|
||||
case "$OS" in
|
||||
Windows* | CYGWIN* )
|
||||
printf "true"
|
||||
;;
|
||||
* )
|
||||
printf "false"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
#
|
||||
# Shell routine to test for the proper rejection of syntactically incorrect
|
||||
# version specifications.
|
||||
@ -139,7 +154,6 @@ CreateUglyJar() {
|
||||
$PACKAGE/UglyPrintVersion.class
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Constructs a jar file with a fair number of "zip directory" entries and
|
||||
# the MANIFEST.MF entry at or near the end of that directory to validate
|
||||
@ -262,6 +276,29 @@ LaunchVM() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Tests very long Main-Class attribute in the jar
|
||||
TestLongMainClass() {
|
||||
JVER=$1
|
||||
if [ "$JVER" = "mklink" ]; then
|
||||
JVER=XX
|
||||
JDKXX=jdk/j2re$JVER
|
||||
rm -rf jdk
|
||||
mkdir jdk
|
||||
ln -s $TESTJAVA $JDKXX
|
||||
JAVA_VERSION_PATH="`pwd`/jdk"
|
||||
export JAVA_VERSION_PATH
|
||||
fi
|
||||
$JAVAEXE -cp $TESTCLASSES ZipMeUp UglyBetty.jar 4097
|
||||
message="`$JAVAEXE -version:$JVER -jar UglyBetty.jar 2>&1`"
|
||||
echo $message | grep "Error: main-class: attribute exceeds system limits" > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
printf "Long manifest test did not get expected error"
|
||||
exit 1
|
||||
fi
|
||||
unset JAVA_VERSION_PATH
|
||||
rm -rf jdk
|
||||
}
|
||||
|
||||
#
|
||||
# Main test sequence starts here
|
||||
#
|
||||
@ -280,14 +317,11 @@ CreateJar "" ""
|
||||
LaunchVM "" "${RELEASE}"
|
||||
CreateJar "" "0"
|
||||
LaunchVM "" "${RELEASE}"
|
||||
case "$OS" in
|
||||
Windows* | CYGWIN* )
|
||||
MAXIMUM_PATH=255;
|
||||
;;
|
||||
*)
|
||||
MAXIMUM_PATH=1024;
|
||||
;;
|
||||
esac
|
||||
if [ `IsWindows` = "true" ]; then
|
||||
MAXIMUM_PATH=255;
|
||||
else
|
||||
MAXIMUM_PATH=1024;
|
||||
fi
|
||||
|
||||
PATH_LENGTH=`printf "%s" "$UGLYCLASS" | wc -c`
|
||||
if [ ${PATH_LENGTH} -lt ${MAXIMUM_PATH} ]; then
|
||||
@ -346,7 +380,6 @@ if [ -x /usr/bin/zipnote ]; then
|
||||
LaunchVM "" "${RELEASE}"
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Throw some syntactically challenged (illegal) version specifiers at
|
||||
# the interface. Failure (of the launcher) is success for the test.
|
||||
@ -357,15 +390,28 @@ TestSyntax "1.2.3-" # Ends with a separator
|
||||
TestSyntax "1.2+.3" # Embedded modifier
|
||||
TestSyntax "1.2.4+&1.2*&1++" # Long and invalid
|
||||
|
||||
# On windows we see if there is another jre installed, usually
|
||||
# there is, then we test using that, otherwise links are created
|
||||
# to get through to SelectVersion.
|
||||
if [ `IsWindows` = "false" ]; then
|
||||
TestLongMainClass "mklink"
|
||||
else
|
||||
$JAVAEXE -version:1.0+
|
||||
if [ $? -eq 0 ]; then
|
||||
TestLongMainClass "1.0+"
|
||||
else
|
||||
printf "Warning: TestLongMainClass skipped as there is no"
|
||||
printf "viable MJRE installed.\n"
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Because scribbling in the registry can be rather destructive, only a
|
||||
# subset of the tests are run on Windows.
|
||||
#
|
||||
case "$OS" in
|
||||
Windows* | CYGWIN* )
|
||||
exit 0;
|
||||
;;
|
||||
esac
|
||||
if [ `IsWindows` = "true" ]; then
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
#
|
||||
# Additional version specifiers containing spaces. (Sigh, unable to
|
||||
|
91
jdk/test/tools/launcher/ZipMeUp.java
Normal file
91
jdk/test/tools/launcher/ZipMeUp.java
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A simple class to create our erring Jar with a very long Main-Class
|
||||
* attribute in the manifest.
|
||||
*/
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.zip.CRC32;
|
||||
import java.util.zip.CheckedOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
public class ZipMeUp {
|
||||
|
||||
static final CRC32 crc = new CRC32();
|
||||
|
||||
private static String SOME_KLASS = ".Some";
|
||||
|
||||
static byte[] getManifestAsBytes(int nchars) throws IOException {
|
||||
crc.reset();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
CheckedOutputStream cos = new CheckedOutputStream(baos, crc);
|
||||
PrintStream ps = new PrintStream(cos);
|
||||
ps.println("Manifest-Version: 1.0");
|
||||
ps.print("Main-Class: ");
|
||||
for (int i = 0 ; i < nchars - SOME_KLASS.length() ; i++) {
|
||||
ps.print(i%10);
|
||||
}
|
||||
ps.println(SOME_KLASS);
|
||||
cos.flush();
|
||||
cos.close();
|
||||
ps.close();
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* The arguments are: filename_to_create length
|
||||
* @param args
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
public static void main(String...args) throws Exception {
|
||||
FileOutputStream fos = new FileOutputStream(args[0]);
|
||||
ZipOutputStream zos = new ZipOutputStream(fos);
|
||||
byte[] manifest = getManifestAsBytes(Integer.parseInt(args[1]));
|
||||
ZipEntry ze = new ZipEntry("META-INF/MANIFEST.MF");
|
||||
ze.setMethod(ZipEntry.STORED);
|
||||
ze.setSize(manifest.length);
|
||||
ze.setCompressedSize(manifest.length);
|
||||
ze.setCrc(crc.getValue());
|
||||
ze.setTime(System.currentTimeMillis());
|
||||
zos.putNextEntry(ze);
|
||||
zos.write(manifest);
|
||||
zos.flush();
|
||||
|
||||
// add a zero length class
|
||||
ze = new ZipEntry(SOME_KLASS + ".class");
|
||||
ze.setMethod(ZipEntry.STORED);
|
||||
ze.setSize(0);
|
||||
ze.setCompressedSize(0);
|
||||
ze.setCrc(0);
|
||||
ze.setTime(System.currentTimeMillis());
|
||||
zos.putNextEntry(ze);
|
||||
zos.flush();
|
||||
zos.closeEntry();
|
||||
zos.close();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user