8300596: Enhance Jar Signature validation
Reviewed-by: mullan, rhalade, mschoene, weijun
This commit is contained in:
parent
fff7e1ad00
commit
ecd0bc1d62
@ -30,6 +30,7 @@ import jdk.internal.access.JavaUtilZipFileAccess;
|
||||
import jdk.internal.misc.ThreadTracker;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import sun.security.util.ManifestEntryVerifier;
|
||||
import sun.security.util.SignatureFileVerifier;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.EOFException;
|
||||
@ -144,8 +145,6 @@ public class JarFile extends ZipFile {
|
||||
private static final Runtime.Version RUNTIME_VERSION;
|
||||
private static final boolean MULTI_RELEASE_ENABLED;
|
||||
private static final boolean MULTI_RELEASE_FORCED;
|
||||
// The maximum size of array to allocate. Some VMs reserve some header words in an array.
|
||||
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
|
||||
|
||||
private SoftReference<Manifest> manRef;
|
||||
private JarEntry manEntry;
|
||||
@ -799,8 +798,11 @@ public class JarFile extends ZipFile {
|
||||
private byte[] getBytes(ZipEntry ze) throws IOException {
|
||||
try (InputStream is = super.getInputStream(ze)) {
|
||||
long uncompressedSize = ze.getSize();
|
||||
if (uncompressedSize > MAX_ARRAY_SIZE) {
|
||||
throw new IOException("Unsupported size: " + uncompressedSize);
|
||||
if (uncompressedSize > SignatureFileVerifier.MAX_SIG_FILE_SIZE) {
|
||||
throw new IOException("Unsupported size: " + uncompressedSize +
|
||||
" for JarEntry " + ze.getName() +
|
||||
". Allowed max size: " +
|
||||
SignatureFileVerifier.MAX_SIG_FILE_SIZE + " bytes");
|
||||
}
|
||||
int len = (int)uncompressedSize;
|
||||
int bytesRead;
|
||||
|
@ -36,6 +36,7 @@ import java.util.*;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import sun.security.action.GetIntegerAction;
|
||||
import sun.security.jca.Providers;
|
||||
import sun.security.pkcs.PKCS7;
|
||||
import sun.security.pkcs.SignerInfo;
|
||||
@ -83,6 +84,12 @@ public class SignatureFileVerifier {
|
||||
|
||||
private static final String META_INF = "META-INF/";
|
||||
|
||||
// the maximum allowed size in bytes for the signature-related files
|
||||
public static final int MAX_SIG_FILE_SIZE = initializeMaxSigFileSize();
|
||||
|
||||
// The maximum size of array to allocate. Some VMs reserve some header words in an array.
|
||||
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
|
||||
|
||||
/**
|
||||
* Create the named SignatureFileVerifier.
|
||||
*
|
||||
@ -833,4 +840,24 @@ public class SignatureFileVerifier {
|
||||
signerCache.add(cachedSigners);
|
||||
signers.put(name, cachedSigners);
|
||||
}
|
||||
|
||||
private static int initializeMaxSigFileSize() {
|
||||
/*
|
||||
* System property "jdk.jar.maxSignatureFileSize" used to configure
|
||||
* the maximum allowed number of bytes for the signature-related files
|
||||
* in a JAR file.
|
||||
*/
|
||||
Integer tmp = GetIntegerAction.privilegedGetProperty(
|
||||
"jdk.jar.maxSignatureFileSize", 8000000);
|
||||
if (tmp < 0 || tmp > MAX_ARRAY_SIZE) {
|
||||
if (debug != null) {
|
||||
debug.println("Default signature file size 8000000 bytes " +
|
||||
"is used as the specified size for the " +
|
||||
"jdk.jar.maxSignatureFileSize system property " +
|
||||
"is out of range: " + tmp);
|
||||
}
|
||||
tmp = 8000000;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
@ -753,6 +753,13 @@ public class Main {
|
||||
&& SignatureFileVerifier.isBlockOrSF(name)) {
|
||||
String alias = name.substring(name.lastIndexOf('/') + 1,
|
||||
name.lastIndexOf('.'));
|
||||
long uncompressedSize = je.getSize();
|
||||
if (uncompressedSize > SignatureFileVerifier.MAX_SIG_FILE_SIZE) {
|
||||
unparsableSignatures.putIfAbsent(alias, String.format(
|
||||
rb.getString("history.unparsable"), name));
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (name.endsWith(".SF")) {
|
||||
Manifest sf = new Manifest(is);
|
||||
|
Loading…
Reference in New Issue
Block a user