diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 7a05c3069db..411d1b03a00 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -354,7 +354,7 @@ void SharedClassPathEntry::copy_from(SharedClassPathEntry* ent, ClassLoaderData* _from_class_path_attr = ent->_from_class_path_attr; set_name(ent->name(), CHECK); - if (ent->is_jar() && !ent->is_signed() && ent->manifest() != nullptr) { + if (ent->is_jar() && ent->manifest() != nullptr) { Array* buf = MetadataFactory::new_array(loader_data, ent->manifest_size(), CHECK); @@ -608,29 +608,6 @@ class ManifestStream: public ResourceObj { buf[len] = 0; return buf; } - - // The return value indicates if the JAR is signed or not - bool check_is_signed() { - u1* attr = _current; - bool isSigned = false; - while (_current < _buffer_end) { - if (*_current == '\n') { - *_current = '\0'; - u1* value = (u1*)strchr((char*)attr, ':'); - if (value != nullptr) { - assert(*(value+1) == ' ', "Unrecognized format" ); - if (strstr((char*)attr, "-Digest") != nullptr) { - isSigned = true; - break; - } - } - *_current = '\n'; // restore - attr = _current + 1; - } - _current ++; - } - return isSigned; - } }; void FileMapInfo::update_jar_manifest(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) { @@ -643,18 +620,14 @@ void FileMapInfo::update_jar_manifest(ClassPathEntry *cpe, SharedClassPathEntry* if (manifest != nullptr) { ManifestStream* stream = new ManifestStream((u1*)manifest, manifest_size); - if (stream->check_is_signed()) { - ent->set_is_signed(); - } else { - // Copy the manifest into the shared archive - manifest = ClassLoaderExt::read_raw_manifest(THREAD, cpe, &manifest_size); - Array* buf = MetadataFactory::new_array(loader_data, - manifest_size, - CHECK); - char* p = (char*)(buf->data()); - memcpy(p, manifest, manifest_size); - ent->set_manifest(buf); - } + // Copy the manifest into the shared archive + manifest = ClassLoaderExt::read_raw_manifest(THREAD, cpe, &manifest_size); + Array* buf = MetadataFactory::new_array(loader_data, + manifest_size, + CHECK); + char* p = (char*)(buf->data()); + memcpy(p, manifest, manifest_size); + ent->set_manifest(buf); } } diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp index 784a2cc6980..963a7011df2 100644 --- a/src/hotspot/share/cds/filemap.hpp +++ b/src/hotspot/share/cds/filemap.hpp @@ -53,7 +53,6 @@ class SharedClassPathEntry : public MetaspaceObj { enum { modules_image_entry, jar_entry, - signed_jar_entry, dir_entry, non_existent_entry, unknown_entry @@ -90,10 +89,6 @@ public: bool is_dir() const { return _type == dir_entry; } bool is_modules_image() const { return _type == modules_image_entry; } bool is_jar() const { return _type == jar_entry; } - bool is_signed() const { return _type == signed_jar_entry; } - void set_is_signed() { - _type = signed_jar_entry; - } bool from_class_path_attr() { return _from_class_path_attr; } time_t timestamp() const { return _timestamp; } const char* name() const; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java b/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java index 46ea9d4f684..b9c2063f3e7 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. 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 @@ -259,21 +259,36 @@ public class JarBuilder { } } + static final String keyTool = JDKToolFinder.getJDKTool("keytool"); + static final String jarSigner = JDKToolFinder.getJDKTool("jarsigner"); - public static void signJar() throws Exception { - String keyTool = JDKToolFinder.getJDKTool("keytool"); - String jarSigner = JDKToolFinder.getJDKTool("jarsigner"); - + public static void signJarWithDisabledAlgorithm(String jarName) throws Exception { + String keyName = "key_with_disabled_alg"; executeProcess(keyTool, - "-genkey", "-keystore", "./keystore", "-alias", "mykey", + "-genkey", "-keystore", "./keystore", "-alias", keyName, + "-storepass", "abc123", "-keypass", "abc123", "-keyalg", "dsa", + "-sigalg", "SHA1withDSA", "-keysize", "512", "-dname", "CN=jvmtest2") + .shouldHaveExitValue(0); + + doSigning(jarName, keyName); + } + + public static void signJar(String jarName) throws Exception { + String keyName = "mykey"; + executeProcess(keyTool, + "-genkey", "-keystore", "./keystore", "-alias", keyName, "-storepass", "abc123", "-keypass", "abc123", "-keyalg", "dsa", "-dname", "CN=jvmtest") .shouldHaveExitValue(0); + doSigning(jarName, keyName); + } + + private static void doSigning(String jarName, String keyName) throws Exception { executeProcess(jarSigner, "-keystore", "./keystore", "-storepass", "abc123", "-keypass", - "abc123", "-signedjar", getJarFilePath("signed_hello"), - getJarFilePath("hello"), "mykey") + "abc123", "-signedjar", getJarFilePath("signed_" + jarName), + getJarFilePath(jarName), keyName) .shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/SealingViolation.java b/test/hotspot/jtreg/runtime/cds/appcds/SealingViolation.java new file mode 100644 index 00000000000..031e98541c4 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/SealingViolation.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8312434 + * @summary A jar file containing classes in the same package. Sign the jar file with + * a disabled algorithm. The jar will be treated as unsigned. + * Dump only one class into the CDS archive. During runtime, load the class + * stored in the archive and then load another class not from the archive + * but from the same pacakge. Loading of the second class should not result + * in sealing violation. + * + * @requires vm.cds + * @library /test/lib + * @compile test-classes/GenericTestApp.java test-classes/pkg/ClassInPackage.java test-classes/C2.java + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox + * @run driver SealingViolation + */ + +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; + +public class SealingViolation { + public static void main(String[] args) throws Exception { + String[] classList = {"pkg/ClassInPackage"}; + String appJar = ClassFileInstaller.writeJar("pkg-classes-sealed.jar", + ClassFileInstaller.Manifest.fromSourceFile("test-classes/pkg/package_seal.mf"), + "GenericTestApp", "pkg/ClassInPackage", "pkg/C2"); + + JarBuilder.signJarWithDisabledAlgorithm("pkg-classes-sealed"); + String signedJar = TestCommon.getTestJar("pkg-classes-sealed.jar"); + + // GenericTestApp requires WhiteBox + String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar"); + String bootclasspath = "-Xbootclasspath/a:" + wbJar; + + OutputAnalyzer output = TestCommon.dump(signedJar, classList, bootclasspath, + "-Xlog:cds+class=debug"); + output.shouldMatch("cds.class.*klasses.*app pkg.ClassInPackage") + .shouldHaveExitValue(0); + + output = TestCommon.exec(signedJar, "-Xlog:cds=debug,class+load", + bootclasspath, + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + "GenericTestApp", + "assertShared:pkg.ClassInPackage", + "assertNotShared:pkg.C2"); + output.shouldHaveExitValue(0); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java b/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java index 850edd6557e..1ad28f99408 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java @@ -38,7 +38,7 @@ import java.io.File; public class SignedJar { public static void main(String[] args) throws Exception { String unsignedJar = JarBuilder.getOrCreateHelloJar(); - JarBuilder.signJar(); + JarBuilder.signJar("hello"); // Test class exists in signed JAR String signedJar = TestCommon.getTestJar("signed_hello.jar"); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/package_seal.mf b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/package_seal.mf new file mode 100644 index 00000000000..ff3d31c53de --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/package_seal.mf @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +Created-By: 1.9.0-internal (Oracle Corporation) + +Name: pkg/ +Sealed: true +