Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 0 additions & 45 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -317,48 +317,3 @@ jobs:
platform: windows-x64
bootjdk-platform: windows-x64
runs-on: windows-2025

# Remove bundles so they are not misconstrued as binary distributions from the JDK project
remove-bundles:
name: 'Remove bundle artifacts'
runs-on: ubuntu-22.04
# SapMachine 2022-06-23: On 'pull_request' we only want to run GHA if the PR comes from a remote repo. Otherwise we have the run on 'push' already as a check.
if: ${{ github.event_name != 'pull_request' || github.repository != 'SAP/SapMachine' }}
needs:
- build-linux-x64
- build-linux-x86
- build-linux-x64-hs-nopch
- build-linux-x64-hs-zero
- build-linux-x64-hs-minimal
- build-linux-x64-hs-optimized
- build-linux-cross-compile
- build-macos-x64
- build-macos-aarch64
- build-windows-x64
- build-windows-aarch64
- test-linux-x64
- test-linux-x86
- test-macos-x64
- test-windows-x64

steps:
- name: 'Remove bundle artifacts'
run: |
# Find and remove all bundle artifacts
# See: https://docs.github.com/en/rest/actions/artifacts?apiVersion=2022-11-28
ALL_ARTIFACT_IDS="$(curl -sL \
-H 'Accept: application/vnd.github+json' \
-H 'Authorization: Bearer ${{ github.token }}' \
-H 'X-GitHub-Api-Version: 2022-11-28' \
'${{ github.api_url }}/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts?per_page=100')"
BUNDLE_ARTIFACT_IDS="$(echo "$ALL_ARTIFACT_IDS" | jq -r -c '.artifacts | map(select(.name|startswith("bundles-"))) | .[].id')"
for id in $BUNDLE_ARTIFACT_IDS; do
echo "Removing $id"
curl -sL \
-X DELETE \
-H 'Accept: application/vnd.github+json' \
-H 'Authorization: Bearer ${{ github.token }}' \
-H 'X-GitHub-Api-Version: 2022-11-28' \
"${{ github.api_url }}/repos/${{ github.repository }}/actions/artifacts/$id" \
|| echo "Failed to remove bundle"
done
15 changes: 10 additions & 5 deletions make/CompileJavaModules.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -531,8 +531,13 @@ jdk.jfr_ADD_JAVAC_FLAGS := -XDstringConcat=inline -Xlint:-exports
################################################################################
# If this is an imported module that has prebuilt classes, only compile
# module-info.java.
ifneq ($(wildcard $(IMPORT_MODULES_CLASSES)/$(MODULE)), )
$(MODULE)_INCLUDE_FILES := module-info.java
ifneq ($(IMPORT_MODULES_CLASSES), )
IMPORT_MODULE_DIR := $(IMPORT_MODULES_CLASSES)/$(MODULE)
ifneq ($(wildcard $(IMPORT_MODULE_DIR)), )
$(MODULE)_INCLUDE_FILES := module-info.java
endif
else
IMPORT_MODULE_DIR :=
endif

################################################################################
Expand Down Expand Up @@ -638,13 +643,13 @@ endif
# If this is an imported module, copy the pre built classes and resources into
# the modules output dir

ifneq ($(wildcard $(IMPORT_MODULES_CLASSES)/$(MODULE)), )
ifneq ($(wildcard $(IMPORT_MODULE_DIR)), )
$(JDK_OUTPUTDIR)/modules/$(MODULE)/_imported.marker: \
$(call FindFiles, $(IMPORT_MODULES_CLASSES)/$(MODULE))
$(call FindFiles, $(IMPORT_MODULE_DIR))
$(call MakeDir, $(@D))
# Do not delete marker and build meta data files
$(RM) -r $(filter-out $(@D)/_%, $(wildcard $(@D)/*))
$(CP) -R $(IMPORT_MODULES_CLASSES)/$(MODULE)/* $(@D)/
$(CP) -R $(IMPORT_MODULE_DIR)/* $(@D)/
$(TOUCH) $@

TARGETS += $(JDK_OUTPUTDIR)/modules/$(MODULE)/_imported.marker
Expand Down
5 changes: 5 additions & 0 deletions src/bsd/doc/man/jarsigner.1
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,11 @@ Informational warnings include those that are not errors but regarded as bad pra
hasExpiringCert
This jar contains entries whose signer certificate will expire within six months\&.
.TP
internalInconsistenciesDetected
This jar contains internal inconsistencies detected during verification
that may result in different contents when reading via JarFile
and JarInputStream\&.
.TP
noTimestamp
This jar contains signatures that does not include a timestamp\&. Without a timestamp, users may not be able to validate this JAR file after the signer certificate\&'s expiration date (\f3YYYY-MM-DD\fR) or after any future revocation date\&.
.SH EXAMPLES
Expand Down
10 changes: 6 additions & 4 deletions src/hotspot/os/linux/cgroupSubsystem_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#include "utilities/globalDefinitions.hpp"

// controller names have to match the *_IDX indices
static const char* cg_controller_name[] = { "cpu", "cpuset", "cpuacct", "memory", "pids" };
static const char* cg_controller_name[] = { "cpuset", "cpu", "cpuacct", "memory", "pids" };

CgroupSubsystem* CgroupSubsystemFactory::create() {
CgroupV1MemoryController* memory = NULL;
Expand Down Expand Up @@ -159,9 +159,10 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos,
char buf[MAXPATHLEN+1];
char *p;
bool is_cgroupsV2;
// true iff all required controllers, memory, cpu, cpuset, cpuacct are enabled
// true iff all required controllers, memory, cpu, cpuacct are enabled
// at the kernel level.
// pids might not be enabled on older Linux distros (SLES 12.1, RHEL 7.1)
// cpuset might not be enabled on newer Linux distros (Fedora 41)
bool all_required_controllers_enabled;

/*
Expand Down Expand Up @@ -193,6 +194,7 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos,
cg_infos[MEMORY_IDX]._hierarchy_id = hierarchy_id;
cg_infos[MEMORY_IDX]._enabled = (enabled == 1);
} else if (strcmp(name, "cpuset") == 0) {
log_debug(os, container)("Detected optional cpuset controller entry in %s", proc_cgroups);
cg_infos[CPUSET_IDX]._name = os::strdup(name);
cg_infos[CPUSET_IDX]._hierarchy_id = hierarchy_id;
cg_infos[CPUSET_IDX]._enabled = (enabled == 1);
Expand All @@ -216,8 +218,8 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos,
is_cgroupsV2 = true;
all_required_controllers_enabled = true;
for (int i = 0; i < CG_INFO_LENGTH; i++) {
// pids controller is optional. All other controllers are required
if (i != PIDS_IDX) {
// pids and cpuset controllers are optional. All other controllers are required
if (i != PIDS_IDX && i != CPUSET_IDX) {
is_cgroupsV2 = is_cgroupsV2 && cg_infos[i]._hierarchy_id == 0;
all_required_controllers_enabled = all_required_controllers_enabled && cg_infos[i]._enabled;
}
Expand Down
148 changes: 148 additions & 0 deletions src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

import java.io.*;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.cert.CertPathValidatorException;
import java.security.cert.PKIXBuilderParameters;
import java.util.*;
Expand Down Expand Up @@ -217,6 +219,8 @@ public static void main(String args[]) throws Exception {
private Throwable chainNotValidatedReason = null;
private Throwable tsaChainNotValidatedReason = null;

private List<String> crossChkWarnings = new ArrayList<>();

PKIXBuilderParameters pkixParameters;
Set<X509Certificate> trustedCerts = new HashSet<>();

Expand Down Expand Up @@ -1045,6 +1049,7 @@ void verifyJar(String jarName)
}
}
System.out.println();
crossCheckEntries(jarName);

if (!anySigned) {
if (disabledAlgFound) {
Expand Down Expand Up @@ -1079,6 +1084,143 @@ void verifyJar(String jarName)
System.exit(1);
}

private void crossCheckEntries(String jarName) throws Exception {
Set<String> locEntries = new HashSet<>();

try (JarFile jarFile = new JarFile(jarName);
JarInputStream jis = new JarInputStream(
Files.newInputStream(Path.of(jarName)))) {

Manifest cenManifest = jarFile.getManifest();
Manifest locManifest = jis.getManifest();
compareManifest(cenManifest, locManifest);

JarEntry locEntry;
while ((locEntry = jis.getNextJarEntry()) != null) {
String entryName = locEntry.getName();
locEntries.add(entryName);

JarEntry cenEntry = jarFile.getJarEntry(entryName);
if (cenEntry == null) {
crossChkWarnings.add(String.format(rb.getString(
"entry.1.present.when.reading.jarinputstream.but.missing.via.jarfile"),
entryName));
continue;
}

try {
readEntry(jis);
} catch (SecurityException e) {
crossChkWarnings.add(String.format(rb.getString(
"signature.verification.failed.on.entry.1.when.reading.via.jarinputstream"),
entryName));
continue;
}

try (InputStream cenInputStream = jarFile.getInputStream(cenEntry)) {
if (cenInputStream == null) {
crossChkWarnings.add(String.format(rb.getString(
"entry.1.present.in.jarfile.but.unreadable"),
entryName));
continue;
} else {
try {
readEntry(cenInputStream);
} catch (SecurityException e) {
crossChkWarnings.add(String.format(rb.getString(
"signature.verification.failed.on.entry.1.when.reading.via.jarfile"),
entryName));
continue;
}
}
}

compareSigners(cenEntry, locEntry);
}

jarFile.stream()
.map(JarEntry::getName)
.filter(n -> !locEntries.contains(n) && !n.equals(JarFile.MANIFEST_NAME))
.forEach(n -> crossChkWarnings.add(String.format(rb.getString(
"entry.1.present.when.reading.jarfile.but.missing.via.jarinputstream"), n)));
}
}

private void readEntry(InputStream is) throws IOException {
is.transferTo(OutputStream.nullOutputStream());
}

private void compareManifest(Manifest cenManifest, Manifest locManifest) {
if (cenManifest == null) {
crossChkWarnings.add(rb.getString(
"manifest.missing.when.reading.jarfile"));
return;
}
if (locManifest == null) {
crossChkWarnings.add(rb.getString(
"manifest.missing.when.reading.jarinputstream"));
return;
}

Attributes cenMainAttrs = cenManifest.getMainAttributes();
Attributes locMainAttrs = locManifest.getMainAttributes();

for (Object key : cenMainAttrs.keySet()) {
Object cenValue = cenMainAttrs.get(key);
Object locValue = locMainAttrs.get(key);

if (locValue == null) {
crossChkWarnings.add(String.format(rb.getString(
"manifest.attribute.1.present.when.reading.jarfile.but.missing.via.jarinputstream"),
key));
} else if (!cenValue.equals(locValue)) {
crossChkWarnings.add(String.format(rb.getString(
"manifest.attribute.1.differs.jarfile.value.2.jarinputstream.value.3"),
key, cenValue, locValue));
}
}

for (Object key : locMainAttrs.keySet()) {
if (!cenMainAttrs.containsKey(key)) {
crossChkWarnings.add(String.format(rb.getString(
"manifest.attribute.1.present.when.reading.jarinputstream.but.missing.via.jarfile"),
key));
}
}
}

private void compareSigners(JarEntry cenEntry, JarEntry locEntry) {
CodeSigner[] cenSigners = cenEntry.getCodeSigners();
CodeSigner[] locSigners = locEntry.getCodeSigners();

boolean cenHasSigners = cenSigners != null;
boolean locHasSigners = locSigners != null;

if (cenHasSigners && locHasSigners) {
if (!Arrays.equals(cenSigners, locSigners)) {
crossChkWarnings.add(String.format(rb.getString(
"codesigners.different.for.entry.1.when.reading.jarfile.and.jarinputstream"),
cenEntry.getName()));
}
} else if (cenHasSigners) {
crossChkWarnings.add(String.format(rb.getString(
"entry.1.is.signed.in.jarfile.but.is.not.signed.in.jarinputstream"),
cenEntry.getName()));
} else if (locHasSigners) {
crossChkWarnings.add(String.format(rb.getString(
"entry.1.is.signed.in.jarinputstream.but.is.not.signed.in.jarfile"),
locEntry.getName()));
}
}

private void displayCrossChkWarnings() {
System.out.println();
// First is a summary warning
System.out.println(rb.getString("jar.contains.internal.inconsistencies.result.in.different.contents.via.jarfile.and.jarinputstream"));
// each warning message with prefix "- "
crossChkWarnings.forEach(warning -> System.out.println("- " + warning));
}

private void displayMessagesAndResult(boolean isSigning) {
String result;
List<String> errors = new ArrayList<>();
Expand Down Expand Up @@ -1314,13 +1456,19 @@ private void displayMessagesAndResult(boolean isSigning) {
System.out.println(rb.getString("Warning."));
warnings.forEach(System.out::println);
}
if (!crossChkWarnings.isEmpty()) {
displayCrossChkWarnings();
}
} else {
if (!errors.isEmpty() || !warnings.isEmpty()) {
System.out.println();
System.out.println(rb.getString("Warning."));
errors.forEach(System.out::println);
warnings.forEach(System.out::println);
}
if (!crossChkWarnings.isEmpty()) {
displayCrossChkWarnings();
}
}
if (!isSigning && (!errors.isEmpty() || !warnings.isEmpty())) {
if (! (verbose != null && showcerts)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,34 @@ public class Resources extends java.util.ListResourceBundle {
{"Cannot.find.environment.variable.",
"Cannot find environment variable: "},
{"Cannot.find.file.", "Cannot find file: "},
{"manifest.missing.when.reading.jarfile",
"Manifest is missing when reading via JarFile"},
{"manifest.missing.when.reading.jarinputstream",
"Manifest is missing when reading via JarInputStream"},
{"manifest.attribute.1.present.when.reading.jarfile.but.missing.via.jarinputstream",
"Manifest main attribute %s is present when reading via JarFile but missing when reading via JarInputStream"},
{"manifest.attribute.1.present.when.reading.jarinputstream.but.missing.via.jarfile",
"Manifest main attribute %s is present when reading via JarInputStream but missing when reading via JarFile"},
{"manifest.attribute.1.differs.jarfile.value.2.jarinputstream.value.3",
"Manifest main attribute %1$s differs: JarFile value = %2$s, JarInputStream value = %3$s"},
{"entry.1.present.when.reading.jarinputstream.but.missing.via.jarfile",
"Entry %s is present when reading via JarInputStream but missing when reading via JarFile"},
{"entry.1.present.when.reading.jarfile.but.missing.via.jarinputstream",
"Entry %s is present when reading via JarFile but missing when reading via JarInputStream"},
{"entry.1.present.in.jarfile.but.unreadable",
"Entry %s is present in JarFile but unreadable"},
{"codesigners.different.for.entry.1.when.reading.jarfile.and.jarinputstream",
"Code signers are different for entry %s when reading from JarFile and JarInputStream"},
{"entry.1.is.signed.in.jarfile.but.is.not.signed.in.jarinputstream",
"Entry %s is signed in JarFile but is not signed in JarInputStream"},
{"entry.1.is.signed.in.jarinputstream.but.is.not.signed.in.jarfile",
"Entry %s is signed in JarInputStream but is not signed in JarFile"},
{"jar.contains.internal.inconsistencies.result.in.different.contents.via.jarfile.and.jarinputstream",
"This JAR file contains internal inconsistencies that may result in different contents when reading via JarFile and JarInputStream:"},
{"signature.verification.failed.on.entry.1.when.reading.via.jarinputstream",
"Signature verification failed on entry %s when reading via JarInputStream"},
{"signature.verification.failed.on.entry.1.when.reading.via.jarfile",
"Signature verification failed on entry %s when reading via JarFile"},
};

/**
Expand Down
5 changes: 5 additions & 0 deletions src/linux/doc/man/jarsigner.1
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,11 @@ Informational warnings include those that are not errors but regarded as bad pra
hasExpiringCert
This jar contains entries whose signer certificate will expire within six months\&.
.TP
internalInconsistenciesDetected
This jar contains internal inconsistencies detected during verification
that may result in different contents when reading via JarFile
and JarInputStream\&.
.TP
noTimestamp
This jar contains signatures that does not include a timestamp\&. Without a timestamp, users may not be able to validate this JAR file after the signer certificate\&'s expiration date (\f3YYYY-MM-DD\fR) or after any future revocation date\&.
.SH EXAMPLES
Expand Down
5 changes: 5 additions & 0 deletions src/solaris/doc/sun/man/man1/jarsigner.1
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,11 @@ Informational warnings include those that are not errors but regarded as bad pra
hasExpiringCert
This jar contains entries whose signer certificate will expire within six months\&.
.TP
internalInconsistenciesDetected
This jar contains internal inconsistencies detected during verification
that may result in different contents when reading via JarFile
and JarInputStream\&.
.TP
noTimestamp
This jar contains signatures that does not include a timestamp\&. Without a timestamp, users may not be able to validate this JAR file after the signer certificate\&'s expiration date (\f3YYYY-MM-DD\fR) or after any future revocation date\&.
.SH EXAMPLES
Expand Down
Loading
Loading