Skip to content

Commit 7fc5e31

Browse files
Alexei VoitylovRealCLanger
authored andcommitted
8300596: Enhance Jar Signature validation
Reviewed-by: yan, mbalao Backport-of: a099d8bf015950db7f0b0ca792e4a9dc951a15cf
1 parent b670cac commit 7fc5e31

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

src/java.base/share/classes/java/util/jar/JarFile.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
2929
import jdk.internal.access.JavaUtilZipFileAccess;
3030
import sun.security.action.GetPropertyAction;
3131
import sun.security.util.ManifestEntryVerifier;
32+
import sun.security.util.SignatureFileVerifier;
3233

3334
import java.io.ByteArrayInputStream;
3435
import java.io.EOFException;
@@ -151,8 +152,6 @@ public class JarFile extends ZipFile {
151152
private static final boolean MULTI_RELEASE_ENABLED;
152153
private static final boolean MULTI_RELEASE_FORCED;
153154
private static final ThreadLocal<Boolean> isInitializing = new ThreadLocal<>();
154-
// The maximum size of array to allocate. Some VMs reserve some header words in an array.
155-
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
156155

157156
private SoftReference<Manifest> manRef;
158157
private JarEntry manEntry;
@@ -800,8 +799,11 @@ private void initializeVerifier() {
800799
private byte[] getBytes(ZipEntry ze) throws IOException {
801800
try (InputStream is = super.getInputStream(ze)) {
802801
long uncompressedSize = ze.getSize();
803-
if (uncompressedSize > MAX_ARRAY_SIZE) {
804-
throw new IOException("Unsupported size: " + uncompressedSize);
802+
if (uncompressedSize > SignatureFileVerifier.MAX_SIG_FILE_SIZE) {
803+
throw new IOException("Unsupported size: " + uncompressedSize +
804+
" for JarEntry " + ze.getName() +
805+
". Allowed max size: " +
806+
SignatureFileVerifier.MAX_SIG_FILE_SIZE + " bytes");
805807
}
806808
int len = (int)uncompressedSize;
807809
int bytesRead;

src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -52,6 +52,7 @@
5252
import java.util.jar.JarFile;
5353
import java.util.jar.Manifest;
5454

55+
import sun.security.action.GetIntegerAction;
5556
import sun.security.jca.Providers;
5657
import sun.security.pkcs.PKCS7;
5758
import sun.security.pkcs.SignerInfo;
@@ -97,6 +98,12 @@ public class SignatureFileVerifier {
9798
/** ConstraintsParameters for checking disabled algorithms */
9899
private JarConstraintsParameters params;
99100

101+
// the maximum allowed size in bytes for the signature-related files
102+
public static final int MAX_SIG_FILE_SIZE = initializeMaxSigFileSize();
103+
104+
// The maximum size of array to allocate. Some VMs reserve some header words in an array.
105+
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
106+
100107
/**
101108
* Create the named SignatureFileVerifier.
102109
*
@@ -842,4 +849,24 @@ void updateSigners(CodeSigner[] newSigners,
842849
signerCache.add(cachedSigners);
843850
signers.put(name, cachedSigners);
844851
}
852+
853+
private static int initializeMaxSigFileSize() {
854+
/*
855+
* System property "jdk.jar.maxSignatureFileSize" used to configure
856+
* the maximum allowed number of bytes for the signature-related files
857+
* in a JAR file.
858+
*/
859+
Integer tmp = GetIntegerAction.privilegedGetProperty(
860+
"jdk.jar.maxSignatureFileSize", 8000000);
861+
if (tmp < 0 || tmp > MAX_ARRAY_SIZE) {
862+
if (debug != null) {
863+
debug.println("Default signature file size 8000000 bytes " +
864+
"is used as the specified size for the " +
865+
"jdk.jar.maxSignatureFileSize system property " +
866+
"is out of range: " + tmp);
867+
}
868+
tmp = 8000000;
869+
}
870+
return tmp;
871+
}
845872
}

src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -728,6 +728,13 @@ void verifyJar(String jarName)
728728
&& SignatureFileVerifier.isBlockOrSF(name)) {
729729
String alias = name.substring(name.lastIndexOf('/') + 1,
730730
name.lastIndexOf('.'));
731+
long uncompressedSize = je.getSize();
732+
if (uncompressedSize > SignatureFileVerifier.MAX_SIG_FILE_SIZE) {
733+
unparsableSignatures.putIfAbsent(alias, String.format(
734+
rb.getString("history.unparsable"), name));
735+
continue;
736+
}
737+
731738
try {
732739
if (name.endsWith(".SF")) {
733740
Manifest sf = new Manifest(is);

0 commit comments

Comments
 (0)