From a868ad757a61ddb2fae72969ceab3c52580d1b34 Mon Sep 17 00:00:00 2001 From: Greg Watts <18669115+gjwatts@users.noreply.github.com> Date: Wed, 22 Jan 2025 13:34:09 -0600 Subject: [PATCH] Prevent security manager in KernelBootstrap in Java 24+ --- .../kernel/boot/internal/KernelBootstrap.java | 7 +- .../ibm/ws/kernel/boot/utils/JavaInfo.java | 108 ++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/utils/JavaInfo.java diff --git a/dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/internal/KernelBootstrap.java b/dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/internal/KernelBootstrap.java index e93f3993adce..7f6ab90eb1fa 100644 --- a/dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/internal/KernelBootstrap.java +++ b/dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/internal/KernelBootstrap.java @@ -39,6 +39,7 @@ import com.ibm.ws.kernel.boot.Launcher; import com.ibm.ws.kernel.boot.ReturnCode; import com.ibm.ws.kernel.boot.security.WLPDynamicPolicy; +import com.ibm.ws.kernel.boot.utils.JavaInfo; import com.ibm.ws.kernel.boot.utils.SequenceNumber; import com.ibm.ws.kernel.internal.classloader.BootstrapChildFirstJarClassloader; import com.ibm.ws.kernel.internal.classloader.BootstrapChildFirstURLClassloader; @@ -305,7 +306,7 @@ public ReturnCode shutdown(boolean force) throws InterruptedException { return serverLock.waitForStop(); } - // Server did not propertly start (no delegate), so stop is fine. + // Server did not properly start (no delegate), so stop is fine. return ReturnCode.OK; } @@ -438,7 +439,7 @@ public ClassLoader run() { * Set Java 2 Security if enabled */ public static void enableJava2SecurityIfSet(BootstrapConfig bootProps, List urlList) { - if (bootProps.get(BootstrapConstants.JAVA_2_SECURITY_PROPERTY) != null) { + if (bootProps.get(BootstrapConstants.JAVA_2_SECURITY_PROPERTY) != null && JavaInfo.majorVersion() < 24) { NameBasedLocalBundleRepository repo = new NameBasedLocalBundleRepository(bootProps.getInstallRoot()); File bestMatchFile = repo.selectBundle("com.ibm.ws.org.eclipse.equinox.region", @@ -493,7 +494,7 @@ private static void processVersion(BootstrapConfig bootProps, String msgKey, Str String bsConsoleFormat = bootProps.get("com.ibm.ws.logging.console.format"); String envConsoleFormat = System.getenv("WLP_LOGGING_CONSOLE_FORMAT"); - //boostrap format should take precedence + //bootstrap format should take precedence String consoleFormat = bsConsoleFormat != null ? bsConsoleFormat : envConsoleFormat; if (productDisplayName == null) { diff --git a/dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/utils/JavaInfo.java b/dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/utils/JavaInfo.java new file mode 100644 index 000000000000..32f9a05d02eb --- /dev/null +++ b/dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/utils/JavaInfo.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2025 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package com.ibm.ws.kernel.boot.utils; + +/** + * A class used for identifying properties of a JDK + */ +public class JavaInfo { + private static JavaInfo instance; + + public static int JAVA_VERSION = majorVersion(); + + private final int MAJOR; + private final int MINOR; + private final int MICRO; + private final int SERVICE_RELEASE; + private final int FIXPACK; + + private JavaInfo() { + String version = System.getProperty("java.version"); + String[] versionElements = version.split("\\D"); // split on non-digits + + // Pre-JDK 9 the java.version is 1.MAJOR.MINOR + // Post-JDK 9 the java.version is MAJOR.MINOR + int i = Integer.parseInt(versionElements[0]) == 1 ? 1 : 0; + MAJOR = Integer.parseInt(versionElements[i++]); + + if (i < versionElements.length) + MINOR = Integer.parseInt(versionElements[i++]); + else + MINOR = 0; + + if (i < versionElements.length) + MICRO = Integer.parseInt(versionElements[i]); + else + MICRO = 0; + + // Parse service release + String buildInfo = System.getProperty("java.specification.version"); + int sr = 0; + int srloc = buildInfo.toLowerCase().indexOf("sr"); + if (srloc > (-1)) { + srloc += 2; + if (srloc < buildInfo.length()) { + int len = 0; + while ((srloc + len < buildInfo.length()) && Character.isDigit(buildInfo.charAt(srloc + len))) { + len++; + } + sr = Integer.parseInt(buildInfo.substring(srloc, srloc + len)); + } + } + SERVICE_RELEASE = sr; + + // Parse fixpack + int fp = 0; + int fploc = buildInfo.toLowerCase().indexOf("fp"); + if (fploc > (-1)) { + fploc += 2; + if (fploc < buildInfo.length()) { + int len = 0; + while ((fploc + len < buildInfo.length()) && Character.isDigit(buildInfo.charAt(fploc + len))) { + len++; + } + fp = Integer.parseInt(buildInfo.substring(fploc, fploc + len)); + } + } + FIXPACK = fp; + } + + private static JavaInfo instance() { + if (instance == null) + instance = new JavaInfo(); + return instance; + } + + public static int majorVersion() { + return instance().MAJOR; + } + + public static int minorVersion() { + return instance().MINOR; + } + + public static int microVersion() { + return instance().MICRO; + } + + public static int serviceRelease() { + return instance().SERVICE_RELEASE; + } + + public static int fixpack() { + return instance().FIXPACK; + } + + @Override + public String toString() { + return "major=" + MAJOR + ", minor=" + MINOR + ", micro=" + MICRO + ", service release=" + SERVICE_RELEASE + + ", fixpack=" + FIXPACK; + } +}