diff --git a/.jcheck/conf b/.jcheck/conf index 75673d36551b..600e31f208e2 100644 --- a/.jcheck/conf +++ b/.jcheck/conf @@ -1,7 +1,7 @@ [general] project=jdk-updates jbs=JDK -version=11.0.30 +version=11.0.31 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists diff --git a/make/autoconf/version-numbers b/make/autoconf/version-numbers index e1653698f51e..d77db625100f 100644 --- a/make/autoconf/version-numbers +++ b/make/autoconf/version-numbers @@ -28,16 +28,16 @@ DEFAULT_VERSION_FEATURE=11 DEFAULT_VERSION_INTERIM=0 -DEFAULT_VERSION_UPDATE=30 +DEFAULT_VERSION_UPDATE=31 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2026-01-20 +DEFAULT_VERSION_DATE=2026-04-21 DEFAULT_VERSION_CLASSFILE_MAJOR=55 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_ACCEPTABLE_BOOT_VERSIONS="10 11" -DEFAULT_PROMOTED_VERSION_PRE= +DEFAULT_PROMOTED_VERSION_PRE=ea LAUNCHER_NAME=openjdk PRODUCT_NAME=OpenJDK diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index ac9d5ac19062..1025c5e40203 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -981,6 +981,15 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, } assert(is_aligned(stack_size, os::vm_page_size()), "stack_size not aligned"); + // Add an additional page to the stack size to reduce its chances of getting large page aligned + // so that the stack does not get backed by a transparent huge page. + size_t default_large_page_size = os::large_page_size(); + if (default_large_page_size != 0 && + stack_size >= default_large_page_size && + is_aligned(stack_size, default_large_page_size)) { + stack_size += os::vm_page_size(); + } + int status = pthread_attr_setstacksize(&attr, stack_size); assert_status(status == 0, status, "pthread_attr_setstacksize"); @@ -4145,6 +4154,10 @@ bool os::Linux::setup_large_page_type(size_t page_size) { } void os::large_page_init() { + // Always initialize the default large page size even if large pages are not being used. + size_t large_page_size = Linux::setup_large_page_size(); + + // Handle the case where we do not want to use huge pages if (!UseLargePages && !UseTransparentHugePages && !UseHugeTLBFS && @@ -4162,7 +4175,6 @@ void os::large_page_init() { return; } - size_t large_page_size = Linux::setup_large_page_size(); UseLargePages = Linux::setup_large_page_type(large_page_size); set_coredump_filter(LARGEPAGES_BIT); diff --git a/src/hotspot/os_cpu/linux_aarch64/globals_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/globals_linux_aarch64.hpp index 360be743ddc9..0a335e1a0458 100644 --- a/src/hotspot/os_cpu/linux_aarch64/globals_linux_aarch64.hpp +++ b/src/hotspot/os_cpu/linux_aarch64/globals_linux_aarch64.hpp @@ -30,10 +30,18 @@ // (see globals.hpp) define_pd_global(bool, DontYieldALot, false); -define_pd_global(intx, ThreadStackSize, 2048); // 0 => use system default -define_pd_global(intx, VMThreadStackSize, 2048); -define_pd_global(intx, CompilerThreadStackSize, 2048); +// Set default stack sizes < 2MB so as to prevent stacks from getting +// large-page aligned and backed by THPs on systems where 2MB is the +// default huge page size. For non-JavaThreads, glibc may add an additional +// guard page to the total stack size, so to keep the default sizes same +// for all the following flags, we set them to 2 pages less than 2MB. On +// systems where 2MB is the default large page size, 4KB is most commonly +// the regular page size. +define_pd_global(intx, ThreadStackSize, 2040); // 0 => use system default +define_pd_global(intx, VMThreadStackSize, 2040); + +define_pd_global(intx, CompilerThreadStackSize, 2040); define_pd_global(uintx,JVMInvokeMethodSlack, 8192); diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp index 98be313be447..745dca08a583 100644 --- a/src/hotspot/share/utilities/exceptions.cpp +++ b/src/hotspot/share/utilities/exceptions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, 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 @@ -415,6 +415,7 @@ void Exceptions::wrap_dynamic_exception(Thread* THREAD) { // Pass through an Error, including BootstrapMethodError, any other form // of linkage error, or say ThreadDeath/OutOfMemoryError if (TraceMethodHandles) { + ResourceMark rm(THREAD); tty->print_cr("[constant/invoke]dynamic passes through an Error for " INTPTR_FORMAT, p2i((void *)exception)); exception->print(); } @@ -423,6 +424,7 @@ void Exceptions::wrap_dynamic_exception(Thread* THREAD) { // Otherwise wrap the exception in a BootstrapMethodError if (TraceMethodHandles) { + ResourceMark rm(THREAD); tty->print_cr("[constant/invoke]dynamic throws BSME for " INTPTR_FORMAT, p2i((void *)exception)); exception->print(); } diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java index 8e8370ba7a00..753219f45900 100644 --- a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java +++ b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, 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 @@ -706,13 +706,16 @@ public void consume(ConnectionContext context, chc.handshakeProducers.put(SSLHandshake.CERTIFICATE.id, SSLHandshake.CERTIFICATE); - List sss = new LinkedList<>(); - for (int id : crm.algorithmIds) { - SignatureScheme ss = SignatureScheme.valueOf(id); - if (ss != null) { - sss.add(ss); - } + List sss = + SignatureScheme.getSupportedAlgorithms( + chc.sslConfig, + chc.algorithmConstraints, chc.negotiatedProtocol, + crm.algorithmIds); + if (sss == null || sss.isEmpty()) { + throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE, + "No supported signature algorithm"); } + chc.peerRequestedSignatureSchemes = sss; chc.peerRequestedCertSignSchemes = sss; // use the same schemes chc.handshakeSession.setPeerSupportedSignatureAlgorithms(sss); diff --git a/src/java.base/share/classes/sun/security/ssl/SignatureAlgorithmsExtension.java b/src/java.base/share/classes/sun/security/ssl/SignatureAlgorithmsExtension.java index a4bc352f47d5..541c51d2c645 100644 --- a/src/java.base/share/classes/sun/security/ssl/SignatureAlgorithmsExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/SignatureAlgorithmsExtension.java @@ -281,6 +281,10 @@ public void consume(ConnectionContext context, shc.sslConfig, shc.algorithmConstraints, shc.negotiatedProtocol, spec.signatureSchemes); + if (sss == null || sss.isEmpty()) { + throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE, + "No supported signature algorithm"); + } shc.peerRequestedSignatureSchemes = sss; // If no "signature_algorithms_cert" extension is present, then @@ -332,7 +336,7 @@ public void absent(ConnectionContext context, if (shc.negotiatedProtocol.useTLS13PlusSpec()) { throw shc.conContext.fatal(Alert.MISSING_EXTENSION, "No mandatory signature_algorithms extension in the " + - "received CertificateRequest handshake message"); + "received ClientHello handshake message"); } } } @@ -516,6 +520,10 @@ public void consume(ConnectionContext context, chc.sslConfig, chc.algorithmConstraints, chc.negotiatedProtocol, spec.signatureSchemes); + if (sss == null || sss.isEmpty()) { + throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE, + "No supported signature algorithm"); + } chc.peerRequestedSignatureSchemes = sss; // If no "signature_algorithms_cert" extension is present, then diff --git a/src/java.base/share/native/libjli/java.c b/src/java.base/share/native/libjli/java.c index a38ddae63d17..34760f3ea6ca 100644 --- a/src/java.base/share/native/libjli/java.c +++ b/src/java.base/share/native/libjli/java.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2022, 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 @@ -51,6 +51,8 @@ */ +#include + #include "java.h" #include "jni.h" @@ -1695,7 +1697,8 @@ TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***parg for (i = 0; i < jargc; i++) { const char *arg = jargv[i]; if (arg[0] == '-' && arg[1] == 'J') { - *nargv++ = ((arg + 2) == NULL) ? NULL : JLI_StringDup(arg + 2); + assert(arg[2] != '\0' && "Invalid JAVA_ARGS or EXTRA_JAVA_ARGS defined by build"); + *nargv++ = JLI_StringDup(arg + 2); } } diff --git a/src/java.desktop/share/classes/sun/awt/image/XbmImageDecoder.java b/src/java.desktop/share/classes/sun/awt/image/XbmImageDecoder.java index 96546662d818..100edd2952ba 100644 --- a/src/java.desktop/share/classes/sun/awt/image/XbmImageDecoder.java +++ b/src/java.desktop/share/classes/sun/awt/image/XbmImageDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2026, 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 @@ -23,13 +23,22 @@ * questions. */ -/*- +/* * Reads xbitmap format images into a DIBitmap structure. */ package sun.awt.image; -import java.io.*; -import java.awt.image.*; +import java.awt.image.ImageConsumer; +import java.awt.image.IndexColorModel; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.lang.Math.multiplyExact; /** * Parse files of the form: @@ -50,6 +59,8 @@ public class XbmImageDecoder extends ImageDecoder { ImageConsumer.COMPLETESCANLINES | ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME); + private static final int MAX_XBM_SIZE = 16384; + private static final int HEADER_SCAN_LIMIT = 100; public XbmImageDecoder(InputStreamImageSource src, InputStream is) { super(src, is); @@ -72,107 +83,155 @@ private static void error(String s1) throws ImageFormatException { * produce an image from the stream. */ public void produceImage() throws IOException, ImageFormatException { - char nm[] = new char[80]; - int c; - int i = 0; - int state = 0; int H = 0; int W = 0; int x = 0; int y = 0; - boolean start = true; + int n = 0; + int state = 0; byte raster[] = null; IndexColorModel model = null; - while (!aborted && (c = input.read()) != -1) { - if ('a' <= c && c <= 'z' || - 'A' <= c && c <= 'Z' || - '0' <= c && c <= '9' || c == '#' || c == '_') { - if (i < 78) - nm[i++] = (char) c; - } else if (i > 0) { - int nc = i; - i = 0; - if (start) { - if (nc != 7 || - nm[0] != '#' || - nm[1] != 'd' || - nm[2] != 'e' || - nm[3] != 'f' || - nm[4] != 'i' || - nm[5] != 'n' || - nm[6] != 'e') - { - error("Not an XBM file"); + + String matchRegex = "\\s*(0[xX])?((?:(?!,|\\};).)+)(,|\\};)"; + String replaceRegex = "0[xX]|,|\\s+|\\};"; + + String line; + int lineNum = 0; + + try (BufferedReader br = new BufferedReader(new InputStreamReader(input))) { + // loop to process XBM header - width, height and create raster + while (!aborted && (line = br.readLine()) != null + && lineNum <= HEADER_SCAN_LIMIT) { + lineNum++; + // process #define stmts + if (line.trim().startsWith("#define")) { + String[] token = line.split("\\s+"); + if (token.length != 3) { + error("Error while parsing define statement"); + } + try { + if (!token[2].isBlank() && state == 0) { + if (token[1].endsWith("th")) { + W = Integer.parseInt(token[2]); + } else if (token[1].endsWith("t")) { + H = Integer.parseInt(token[2]); + } + state = 1; // after first dimension is set + } else if (!token[2].isBlank() && state == 1) { + if (token[1].endsWith("th")) { + W = Integer.parseInt(token[2]); + } else if (token[1].endsWith("t")) { + H = Integer.parseInt(token[2]); + } + state = 2; // after second dimension is set + } + } catch (NumberFormatException nfe) { + // parseInt() can throw NFE + error("Error while parsing width or height."); } - start = false; } - if (nm[nc - 1] == 'h') - state = 1; /* expecting width */ - else if (nm[nc - 1] == 't' && nc > 1 && nm[nc - 2] == 'h') - state = 2; /* expecting height */ - else if (nc > 2 && state < 0 && nm[0] == '0' && nm[1] == 'x') { - int n = 0; - for (int p = 2; p < nc; p++) { - c = nm[p]; - if ('0' <= c && c <= '9') - c = c - '0'; - else if ('A' <= c && c <= 'Z') - c = c - 'A' + 10; - else if ('a' <= c && c <= 'z') - c = c - 'a' + 10; - else - c = 0; - n = n * 16 + c; + + if (state == 2) { + if (W <= 0 || H <= 0) { + error("Invalid values for width or height."); } - for (int mask = 1; mask <= 0x80; mask <<= 1) { - if (x < W) { - if ((n & mask) != 0) - raster[x] = 1; - else - raster[x] = 0; - } - x++; + if (multiplyExact(W, H) > MAX_XBM_SIZE) { + error("Large XBM file size." + + " Maximum allowed size: " + MAX_XBM_SIZE); } - if (x >= W) { - if (setPixels(0, y, W, 1, model, raster, 0, W) <= 0) { - return; - } - x = 0; - if (y++ >= H) { - break; - } + model = new IndexColorModel(8, 2, XbmColormap, + 0, false, 0); + setDimensions(W, H); + setColorModel(model); + setHints(XbmHints); + headerComplete(); + raster = new byte[W]; + state = 3; + break; + } + } + + if (state != 3) { + error("Width or Height of XBM file not defined"); + } + + boolean contFlag = false; + StringBuilder sb = new StringBuilder(); + + // loop to process image data + while (!aborted && (line = br.readLine()) != null) { + lineNum++; + + if (!contFlag) { + if (line.contains("[]")) { + contFlag = true; + } else { + continue; } + } + + int end = line.indexOf(';'); + if (end >= 0) { + sb.append(line, 0, end + 1); + break; } else { - int n = 0; - for (int p = 0; p < nc; p++) - if ('0' <= (c = nm[p]) && c <= '9') - n = n * 10 + c - '0'; - else { - n = -1; - break; - } - if (n > 0 && state > 0) { - if (state == 1) - W = n; + sb.append(line).append(System.lineSeparator()); + } + } + + String resultLine = sb.toString(); + int cutOffIndex = resultLine.indexOf('{'); + resultLine = resultLine.substring(cutOffIndex + 1); + + Matcher matcher = Pattern.compile(matchRegex).matcher(resultLine); + while (matcher.find()) { + if (y >= H) { + error("Scan size of XBM file exceeds" + + " the defined width x height"); + } + + int startIndex = matcher.start(); + int endIndex = matcher.end(); + String hexByte = resultLine.substring(startIndex, endIndex); + hexByte = hexByte.replaceAll("^\\s+", ""); + + if (!(hexByte.startsWith("0x") + || hexByte.startsWith("0X"))) { + error("Invalid hexadecimal number at Ln#:" + lineNum + + " Col#:" + (startIndex + 1)); + } + hexByte = hexByte.replaceAll(replaceRegex, ""); + if (hexByte.length() != 2) { + error("Invalid hexadecimal number at Ln#:" + lineNum + + " Col#:" + (startIndex + 1)); + } + + try { + n = Integer.parseInt(hexByte, 16); + } catch (NumberFormatException nfe) { + error("Error parsing hexadecimal at Ln#:" + lineNum + + " Col#:" + (startIndex + 1)); + } + for (int mask = 1; mask <= 0x80; mask <<= 1) { + if (x < W) { + if ((n & mask) != 0) + raster[x] = 1; else - H = n; - if (W == 0 || H == 0) - state = 0; - else { - model = new IndexColorModel(8, 2, XbmColormap, - 0, false, 0); - setDimensions(W, H); - setColorModel(model); - setHints(XbmHints); - headerComplete(); - raster = new byte[W]; - state = -1; - } + raster[x] = 0; + } + x++; + } + + if (x >= W) { + int result = setPixels(0, y, W, 1, model, raster, 0, W); + if (result <= 0) { + error("Unexpected error occurred during setPixel()"); } + x = 0; + y++; } } + imageComplete(ImageConsumer.STATICIMAGEDONE, true); } - input.close(); - imageComplete(ImageConsumer.STATICIMAGEDONE, true); } } diff --git a/src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.c b/src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.c index 0d834302c575..2bae3ed4a5d3 100644 --- a/src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.c +++ b/src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.c @@ -38,7 +38,11 @@ #define amd64 1 #endif -#ifdef i386 +#if defined(i386) && !defined(i586) +#define i586 1 +#endif + +#ifdef i586 #include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h" #endif @@ -397,7 +401,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo return (err == PS_OK)? array : 0; } -#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64) || defined(ppc64le) || defined(aarch64) +#if defined(i586) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64) || defined(ppc64le) || defined(aarch64) JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0 (JNIEnv *env, jobject this_obj, jint lwp_id) { @@ -413,7 +417,7 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo } #undef NPRGREG -#ifdef i386 +#ifdef i586 #define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG #endif #ifdef amd64 @@ -436,7 +440,7 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo #undef REG_INDEX -#ifdef i386 +#ifdef i586 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg regs[REG_INDEX(GS)] = (uintptr_t) gregs.xgs; @@ -455,7 +459,7 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo regs[REG_INDEX(CS)] = (uintptr_t) gregs.xcs; regs[REG_INDEX(SS)] = (uintptr_t) gregs.xss; -#endif /* i386 */ +#endif /* i586 */ #ifdef amd64 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg diff --git a/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c b/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c index dc66033e4826..737e2fb10bda 100644 --- a/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c +++ b/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c @@ -1109,7 +1109,7 @@ static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size if (is_debug()) { print_debug("integer regset\n"); -#ifdef i386 +#if defined(i586) || defined(i386) // print the regset print_debug("\teax = 0x%x\n", newthr->regs.r_eax); print_debug("\tebx = 0x%x\n", newthr->regs.r_ebx); diff --git a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java index 00325644345d..6cb1e79f23dc 100644 --- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java +++ b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, 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 @@ -33,7 +33,7 @@ * @library /test/lib * @modules java.base/jdk.internal.misc * java.management - * @build sun.hotspot.WhiteBox + * @build sun.hotspot.WhiteBox SurvivorAlignmentTestMain AlignmentHelper * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions diff --git a/test/hotspot/jtreg/testlibrary/jittester/conf/default.properties b/test/hotspot/jtreg/testlibrary/jittester/conf/default.properties index 2582c598fdfe..8de6d9a43002 100644 --- a/test/hotspot/jtreg/testlibrary/jittester/conf/default.properties +++ b/test/hotspot/jtreg/testlibrary/jittester/conf/default.properties @@ -8,6 +8,6 @@ classes-file=conf/classes.lst exclude-methods-file=conf/exclude.methods.lst print-complexity=true print-hierarchy=true -disable-static=true +disable-static=false generatorsFactories=jdk.test.lib.jittester.TestGeneratorsFactory,jdk.test.lib.jittester.AotTestGeneratorsFactory generators=JavaCode,ByteCode diff --git a/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StaticConstructorDefinitionFactory.java b/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StaticConstructorDefinitionFactory.java index 0a77fbb7d2c3..0354559bf67d 100644 --- a/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StaticConstructorDefinitionFactory.java +++ b/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StaticConstructorDefinitionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, 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 @@ -63,7 +63,7 @@ public StaticConstructorDefinition produce() throws ProductionFailedException { .setOperatorLimit(operatorLimit) .setLevel(level) .setSubBlock(true) - .setCanHaveBreaks(true) + .setCanHaveBreaks(false) .setCanHaveContinues(false) .setCanHaveReturn(false) .getBlockFactory() diff --git a/test/jdk/java/awt/image/XBMDecoder/XBMDecoderTest.java b/test/jdk/java/awt/image/XBMDecoder/XBMDecoderTest.java new file mode 100644 index 000000000000..9694043d1bb9 --- /dev/null +++ b/test/jdk/java/awt/image/XBMDecoder/XBMDecoderTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2026, 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 8361748 + * @summary Tests XBM image size limits and if XBMImageDecoder.produceImage() + * throws appropriate error when parsing invalid XBM image data. + * @run main XBMDecoderTest + */ + +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.PrintStream; +import java.util.Arrays; +import javax.swing.ImageIcon; + +public class XBMDecoderTest { + + public static void main(String[] args) throws Exception { + String dir = System.getProperty("test.src"); + PrintStream originalErr = System.err; + boolean validCase; + + File currentDir = new File(dir); + File[] files = currentDir.listFiles((File d, String s) + -> s.endsWith(".xbm")); + + for (File file : files) { + String fileName = file.getName(); + validCase = fileName.startsWith("valid"); + + System.out.println("--- Testing " + fileName + " ---"); + try (FileInputStream fis = new FileInputStream(file); + ByteArrayOutputStream errContent = new ByteArrayOutputStream()) { + System.setErr(new PrintStream(errContent)); + + ImageIcon icon = new ImageIcon(fis.readAllBytes()); + boolean isErrEmpty = errContent.toString().isEmpty(); + + if (!isErrEmpty) { + System.out.println("Expected ImageFormatException occurred."); + System.out.print(errContent); + } + if (validCase && !isErrEmpty) { + throw new RuntimeException("Test failed: Error stream not empty"); + } else if (!validCase && isErrEmpty && hasPixelData(icon.getImage())) { + throw new RuntimeException("Test failed: ImageFormatException" + + " expected but not thrown"); + } + if (validCase && !hasPixelData(icon.getImage())) { + throw new RuntimeException("Test failed: the parsed image " + + "does not contain any pixel data"); + } + System.out.println("PASSED\n"); + } finally { + System.setErr(originalErr); + } + } + } + + private static boolean hasPixelData(Image img) { + int w = img.getWidth(null); + int h = img.getHeight(null); + BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = bi.createGraphics(); + g.drawImage(img, 0, 0, null); + g.dispose(); + int[] pixels = bi.getRGB(0, 0, w, h, null, 0, w); + if (Arrays.stream(pixels).allMatch(i -> i == 0)) { + return false; + } + return true; + } +} diff --git a/test/jdk/java/awt/image/XBMDecoder/invalid.xbm b/test/jdk/java/awt/image/XBMDecoder/invalid.xbm new file mode 100644 index 000000000000..8a8cfc276322 --- /dev/null +++ b/test/jdk/java/awt/image/XBMDecoder/invalid.xbm @@ -0,0 +1,2 @@ +#define k_ht 3 +h` k[] = { 01x0, 42222222222236319330:: diff --git a/test/jdk/java/awt/image/XBMDecoder/invalid_empty.xbm b/test/jdk/java/awt/image/XBMDecoder/invalid_empty.xbm new file mode 100644 index 000000000000..5cfb8e21cf87 --- /dev/null +++ b/test/jdk/java/awt/image/XBMDecoder/invalid_empty.xbm @@ -0,0 +1,6 @@ +#define test_width 16 +#define test_height 3 +#define ht_x 1 +#define ht_y 2 +static unsigned char test_bits[] = { +}; diff --git a/test/jdk/java/awt/image/XBMDecoder/invalid_hex.xbm b/test/jdk/java/awt/image/XBMDecoder/invalid_hex.xbm new file mode 100644 index 000000000000..1286eee1d9bb --- /dev/null +++ b/test/jdk/java/awt/image/XBMDecoder/invalid_hex.xbm @@ -0,0 +1,3 @@ +#define k_width 16 +#define k_height 1 +k[] = { 0x10, 1234567890}; diff --git a/test/jdk/java/awt/image/XBMDecoder/invalid_ht.xbm b/test/jdk/java/awt/image/XBMDecoder/invalid_ht.xbm new file mode 100644 index 000000000000..5244651a4cb4 --- /dev/null +++ b/test/jdk/java/awt/image/XBMDecoder/invalid_ht.xbm @@ -0,0 +1,3 @@ +#define k_wt 16 +#define k_ht 0 +k[] = { 0x10, 0x12}; diff --git a/test/jdk/java/awt/image/XBMDecoder/invalid_plus.xbm b/test/jdk/java/awt/image/XBMDecoder/invalid_plus.xbm new file mode 100644 index 000000000000..714907084f29 --- /dev/null +++ b/test/jdk/java/awt/image/XBMDecoder/invalid_plus.xbm @@ -0,0 +1,3 @@ +#define test_width 16 +#define test_height 2 +static unsigned char test_bits[] = { 0x13, 0x11, 0xAB+, 0xff }; \ No newline at end of file diff --git a/test/jdk/java/awt/image/XBMDecoder/valid.xbm b/test/jdk/java/awt/image/XBMDecoder/valid.xbm new file mode 100644 index 000000000000..23b57b2c8116 --- /dev/null +++ b/test/jdk/java/awt/image/XBMDecoder/valid.xbm @@ -0,0 +1,6 @@ +#define test_width 16 +#define test_height 3 +#define ht_x 1 +#define ht_y 2 +static unsigned char test_bits[] = { +0x13, 0x11, 0x15, 0x00, 0xAB, 0xcd }; diff --git a/test/jdk/java/awt/image/XBMDecoder/valid_hex.xbm b/test/jdk/java/awt/image/XBMDecoder/valid_hex.xbm new file mode 100644 index 000000000000..e365d8024472 --- /dev/null +++ b/test/jdk/java/awt/image/XBMDecoder/valid_hex.xbm @@ -0,0 +1,4 @@ +#define test_width 16 +#define test_height 2 +static unsigned char test_bits[] = { 0x13, 0x11, + 0xAB, 0xff }; diff --git a/test/jdk/java/awt/image/XBMDecoder/valid_multiline.xbm b/test/jdk/java/awt/image/XBMDecoder/valid_multiline.xbm new file mode 100644 index 000000000000..e24bc10e9b0c --- /dev/null +++ b/test/jdk/java/awt/image/XBMDecoder/valid_multiline.xbm @@ -0,0 +1,8 @@ +#define test_width 16 +#define test_height 3 +#define ht_x 1 +#define ht_y 2 +static unsigned char test_bits[] = { +0x20, 0x10, +0x25, 0x01, +0xAC, 0xab }; diff --git a/test/jdk/javax/net/ssl/templates/SSLContextTemplate.java b/test/jdk/javax/net/ssl/templates/SSLContextTemplate.java index f3cad4ddfe16..fd2fcd8099d5 100644 --- a/test/jdk/javax/net/ssl/templates/SSLContextTemplate.java +++ b/test/jdk/javax/net/ssl/templates/SSLContextTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, 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 @@ -478,7 +478,7 @@ private SSLContext createSSLContext( /* * Create an instance of KeyManager with the specified key materials. */ - private KeyManager createKeyManager( + static KeyManager createKeyManager( String[] keyMaterialCerts, String[] keyMaterialKeys, String[] keyMaterialKeyAlgs, @@ -534,7 +534,7 @@ private KeyManager createKeyManager( /* * Create an instance of TrustManager with the specified trust materials. */ - private TrustManager createTrustManager( + static TrustManager createTrustManager( String[] trustedMaterials, ContextParameters params) throws Exception { diff --git a/test/jdk/javax/net/ssl/templates/SSLEngineTemplate.java b/test/jdk/javax/net/ssl/templates/SSLEngineTemplate.java index 48a7c19df74a..621aaea35463 100644 --- a/test/jdk/javax/net/ssl/templates/SSLEngineTemplate.java +++ b/test/jdk/javax/net/ssl/templates/SSLEngineTemplate.java @@ -197,7 +197,7 @@ private void runTest() throws Exception { } } - private static boolean isOpen(SSLEngine engine) { + static boolean isOpen(SSLEngine engine) { return (!engine.isOutboundDone() || !engine.isInboundDone()); } @@ -240,7 +240,7 @@ protected static void runDelegatedTasks(SSLEngine engine) throws Exception { } // Simple check to make sure everything came across as expected. - private static void checkTransfer(ByteBuffer a, ByteBuffer b) + static void checkTransfer(ByteBuffer a, ByteBuffer b) throws Exception { a.flip(); b.flip(); diff --git a/test/jdk/sun/security/ssl/SignatureScheme/SigAlgosExtTestWithTLS12.java b/test/jdk/sun/security/ssl/SignatureScheme/SigAlgosExtTestWithTLS12.java new file mode 100644 index 000000000000..f7eb7cf3e911 --- /dev/null +++ b/test/jdk/sun/security/ssl/SignatureScheme/SigAlgosExtTestWithTLS12.java @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2021, Tencent. 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 8263188 + * @summary If TLS the server and client has no common signature algorithms, + * the connection should fail fast with "No supported signature algorithm". + * This test only covers TLS 1.2. + * + * @library /test/lib + * /javax/net/ssl/templates + * + * @run main/othervm + * -Djdk.tls.server.SignatureSchemes=ecdsa_secp384r1_sha384 + * -Djdk.tls.client.SignatureSchemes=ecdsa_secp256r1_sha256,ecdsa_secp384r1_sha384 + * -Dtest.clientAuth=false + * -Dtest.expectFail=false + * SigAlgosExtTestWithTLS12 + * @run main/othervm + * -Djdk.tls.server.SignatureSchemes=ecdsa_secp384r1_sha384 + * -Djdk.tls.client.SignatureSchemes=ecdsa_secp256r1_sha256 + * -Dtest.clientAuth=false + * -Dtest.expectFail=true + * SigAlgosExtTestWithTLS12 + * @run main/othervm + * -Djdk.tls.server.SignatureSchemes=ecdsa_secp256r1_sha256 + * -Djdk.tls.client.SignatureSchemes=ecdsa_secp256r1_sha256 + * -Dtest.clientAuth=true + * -Dtest.expectFail=true + * SigAlgosExtTestWithTLS12 + */ + +import javax.net.ssl.*; +import java.nio.ByteBuffer; +import java.util.*; + +public class SigAlgosExtTestWithTLS12 extends SSLEngineTemplate { + + private static final boolean CLIENT_AUTH + = Boolean.getBoolean("test.clientAuth"); + private static final boolean EXPECT_FAIL + = Boolean.getBoolean("test.expectFail"); + + private static final String[] CA_CERTS = new String[] { + // SHA256withECDSA, curve secp256r1 + // Validity + // Not Before: May 22 07:18:16 2018 GMT + // Not After : May 17 07:18:16 2038 GMT + // Subject Key Identifier: + // 60:CF:BD:73:FF:FA:1A:30:D2:A4:EC:D3:49:71:46:EF:1A:35:A0:86 + "-----BEGIN CERTIFICATE-----\n" + + "MIIBvjCCAWOgAwIBAgIJAIvFG6GbTroCMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" + + "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" + + "ZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMDsxCzAJBgNVBAYTAlVT\n" + + "MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTBZ\n" + + "MBMGByqGSM49AgEGCCqGSM49AwEHA0IABBz1WeVb6gM2mh85z3QlvaB/l11b5h0v\n" + + "LIzmkC3DKlVukZT+ltH2Eq1oEkpXuf7QmbM0ibrUgtjsWH3mULfmcWmjUDBOMB0G\n" + + "A1UdDgQWBBRgz71z//oaMNKk7NNJcUbvGjWghjAfBgNVHSMEGDAWgBRgz71z//oa\n" + + "MNKk7NNJcUbvGjWghjAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQCG\n" + + "6wluh1r2/T6L31mZXRKf9JxeSf9pIzoLj+8xQeUChQIhAJ09wAi1kV8yePLh2FD9\n" + + "2YEHlSQUAbwwqCDEVB5KxaqP\n" + + "-----END CERTIFICATE-----", + + // SHA384withECDSA, curve secp384r1 + // Validity + // Not Before: Jun 24 08:15:06 2019 GMT + // Not After : Jun 19 08:15:06 2039 GMT + // Subject Key Identifier: + // 0a:93:a9:a0:bf:e7:d5:48:9d:4f:89:15:c6:51:98:80:05:51:4e:4e + "-----BEGIN CERTIFICATE-----\n" + + "MIICCDCCAY6gAwIBAgIUCpOpoL/n1UidT4kVxlGYgAVRTk4wCgYIKoZIzj0EAwMw\n" + + "OzELMAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0Ug\n" + + "VGVzdCBTZXJpdmNlMB4XDTE5MDYyNDA4MTUwNloXDTM5MDYxOTA4MTUwNlowOzEL\n" + + "MAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVz\n" + + "dCBTZXJpdmNlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAENVQN1wXWFdgC6u/dDdiC\n" + + "y+WtMTF66oL/0BSm+1ZqsogamzCryawOcHgiuXgWzx5CQ3LuOC+tDFyXpGfHuCvb\n" + + "dkzxPrP5n9NrR8/uRPe5l1KOUbchviU8z9cTP+LZxnZDo1MwUTAdBgNVHQ4EFgQU\n" + + "SktSFArR1p/5mXV0kyo0RxIVa/UwHwYDVR0jBBgwFoAUSktSFArR1p/5mXV0kyo0\n" + + "RxIVa/UwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjBZvoNmq3/v\n" + + "RD2gBTyvxjS9h0rsMRLHDnvul/KWngytwGPTOBo0Y8ixQXSjdKoc3rkCMQDkiNgx\n" + + "IDxuHedmrLQKIPnVcthTmwv7//jHiqGoKofwChMo2a1P+DQdhszmeHD/ARQ=\n" + + "-----END CERTIFICATE-----" + }; + + private static final String[] EE_CERTS = new String[] { + // SHA256withECDSA, curve secp256r1 + // Validity + // Not Before: May 22 07:18:16 2018 GMT + // Not After : May 17 07:18:16 2038 GMT + // Authority Key Identifier: + // 60:CF:BD:73:FF:FA:1A:30:D2:A4:EC:D3:49:71:46:EF:1A:35:A0:86 + "-----BEGIN CERTIFICATE-----\n" + + "MIIBqjCCAVCgAwIBAgIJAPLY8qZjgNRAMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" + + "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" + + "ZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMFUxCzAJBgNVBAYTAlVT\n" + + "MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTEY\n" + + "MBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n" + + "QgAEb+9n05qfXnfHUb0xtQJNS4JeSi6IjOfW5NqchvKnfJey9VkJzR7QHLuOESdf\n" + + "xlR7q8YIWgih3iWLGfB+wxHiOqMjMCEwHwYDVR0jBBgwFoAUYM+9c//6GjDSpOzT\n" + + "SXFG7xo1oIYwCgYIKoZIzj0EAwIDSAAwRQIgWpRegWXMheiD3qFdd8kMdrkLxRbq\n" + + "1zj8nQMEwFTUjjQCIQDRIrAjZX+YXHN9b0SoWWLPUq0HmiFIi8RwMnO//wJIGQ==\n" + + "-----END CERTIFICATE-----", + + // SHA384withECDSA, curve secp384r1 + // Validity + // Not Before: Jun 24 08:15:06 2019 GMT + // Not After : Jun 19 08:15:06 2039 GMT + // Authority Key Identifier: + // 40:2D:AA:EE:66:AA:33:27:AD:9B:5D:52:9B:60:67:6A:2B:AD:52:D2 + "-----BEGIN CERTIFICATE-----\n" + + "MIICEjCCAZegAwIBAgIUS3F0AqAXWRg07CnbknJzxofyBQMwCgYIKoZIzj0EAwMw\n" + + "OzELMAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0Ug\n" + + "VGVzdCBTZXJpdmNlMB4XDTE5MDYyNDA4MTUwNloXDTM5MDYxOTA4MTUwNlowVTEL\n" + + "MAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVz\n" + + "dCBTZXJpdmNlMRgwFgYDVQQDDA9SZWdyZXNzaW9uIFRlc3QwdjAQBgcqhkjOPQIB\n" + + "BgUrgQQAIgNiAARqElz8b6T07eyKomIinhztV3/3XBk9bKGtJ0W+JOltjuhMmP/w\n" + + "G8ASSevpgqgpi6EzpBZaaJxE3zNfkNnxXOZmQi2Ypd1uK0zRdbEOKg0XOcTTZwEj\n" + + "iLjYmt3O0pwpklijQjBAMB0GA1UdDgQWBBRALaruZqozJ62bXVKbYGdqK61S0jAf\n" + + "BgNVHSMEGDAWgBRKS1IUCtHWn/mZdXSTKjRHEhVr9TAKBggqhkjOPQQDAwNpADBm\n" + + "AjEArVDFKf48xijN6huVUJzKCOP0zlWB5Js+DItIkZmLQuhciPLhLIB/rChf3Y4C\n" + + "xuP4AjEAmfLhQRI0O3pifpYzYSVh2G7/jHNG4eO+2dvgAcU+Lh2IIj/cpLaPFSvL\n" + + "J8FXY9Nj\n" + + "-----END CERTIFICATE-----" + }; + + private static final String[] EE_KEYS = new String[] { + "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgn5K03bpTLjEtFQRa\n" + + "JUtx22gtmGEvvSUSQdimhGthdtihRANCAARv72fTmp9ed8dRvTG1Ak1Lgl5KLoiM\n" + + "59bk2pyG8qd8l7L1WQnNHtAcu44RJ1/GVHurxghaCKHeJYsZ8H7DEeI6", + "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDASuI9EtK29APXPipkc\n" + + "qDA+qwlewMjv/OcjUJ77kP1Vz62oVF9iY9SRIyFIUju8wt+hZANiAARqElz8b6T0\n" + + "7eyKomIinhztV3/3XBk9bKGtJ0W+JOltjuhMmP/wG8ASSevpgqgpi6EzpBZaaJxE\n" + + "3zNfkNnxXOZmQi2Ypd1uK0zRdbEOKg0XOcTTZwEjiLjYmt3O0pwpklg=" + }; + + private static final String[] EE_ALGS = new String[] { + "EC", + "EC" + }; + + private static final String[] EE_ALIASES = new String[] { + "EC-SHA256", + "EC-SHA384" + }; + + private static final Map SIG_SCHEMES_MAP = Map.of( + 0x0403, "ecdsa_secp256r1_sha256", + 0x0503, "ecdsa_secp384r1_sha384"); + + private static final int TLS_HS_CLI_HELLO = 1; + private static final int TLS_HS_CERT_REQ = 13; + private static final int HELLO_EXT_SIG_ALGS = 13; + + public SigAlgosExtTestWithTLS12() throws Exception { + super(); + } + + /* + * Create an instance of KeyManager for client use. + */ + public KeyManager createClientKeyManager() throws Exception { + return SSLContextTemplate.createKeyManager( + EE_CERTS, + EE_KEYS, + EE_ALGS, + EE_ALIASES, + getServerContextParameters()); + } + + @Override + public TrustManager createClientTrustManager() throws Exception { + return SSLContextTemplate.createTrustManager( + CA_CERTS, + getServerContextParameters()); + } + + @Override + public KeyManager createServerKeyManager() throws Exception { + return SSLContextTemplate.createKeyManager( + EE_CERTS, + EE_KEYS, + EE_ALGS, + EE_ALIASES, + getServerContextParameters()); + } + + @Override + public TrustManager createServerTrustManager() throws Exception { + return SSLContextTemplate.createTrustManager( + CA_CERTS, + getServerContextParameters()); + } + + @Override + protected SSLEngine configureServerEngine(SSLEngine serverEngine) { + serverEngine.setUseClientMode(false); + serverEngine.setNeedClientAuth(CLIENT_AUTH); + return serverEngine; + } + + @Override + protected SSLEngine configureClientEngine(SSLEngine clientEngine) { + clientEngine.setUseClientMode(true); + clientEngine.setEnabledProtocols(new String[] { "TLSv1.2" }); + return clientEngine; + } + + public static void main(String[] args) throws Exception { + System.setProperty("javax.net.debug", "ssl:handshake"); + + try { + new SigAlgosExtTestWithTLS12().run(); + if (EXPECT_FAIL) { + throw new RuntimeException( + "Expected SSLHandshakeException wasn't thrown"); + } + } catch (SSLHandshakeException e) { + if (EXPECT_FAIL && e.getMessage().equals( + "No supported signature algorithm")) { + System.out.println("Expected SSLHandshakeException"); + } else { + throw e; + } + } + } + + private void run() throws Exception { + boolean dataDone = false; + while (isOpen(clientEngine) || isOpen(serverEngine)) { + clientEngine.wrap(clientOut, cTOs); + cTOs.flip(); + + // Consume the ClientHello and get the server flight of handshake + // messages. We expect that it will be one TLS record containing + // multiple handshake messages, one of which is a CertificateRequest + // when the client authentication is required. + serverEngine.unwrap(cTOs, serverIn); + runDelegatedTasks(serverEngine); + + // Wrap the server flight + serverEngine.wrap(serverOut, sTOc); + sTOc.flip(); + + if (CLIENT_AUTH && EXPECT_FAIL) { + twistCertReqMsg(sTOc); + } + + clientEngine.unwrap(sTOc, clientIn); + runDelegatedTasks(clientEngine); + + serverEngine.unwrap(cTOs, serverIn); + runDelegatedTasks(serverEngine); + + cTOs.compact(); + sTOc.compact(); + + if (!dataDone && (clientOut.limit() == serverIn.position()) && + (serverOut.limit() == clientIn.position())) { + checkTransfer(serverOut, clientIn); + checkTransfer(clientOut, serverIn); + + clientEngine.closeOutbound(); + dataDone = true; + serverEngine.closeOutbound(); + } + } + } + + /** + * Twists signature schemes in CertificateRequest message for negative + * client authentication cases. + * + * @param tlsRecord a ByteBuffer containing a TLS record. It is assumed + * that the position of the ByteBuffer is on the first byte of the TLS + * record header. + * + * @throws SSLException if the incoming ByteBuffer does not contain a + * well-formed TLS message. + */ + private static void twistCertReqMsg( + ByteBuffer tlsRecord) throws SSLException { + Objects.requireNonNull(tlsRecord); + tlsRecord.mark(); + + // Process the TLS record header + int type = Byte.toUnsignedInt(tlsRecord.get()); + int ver_major = Byte.toUnsignedInt(tlsRecord.get()); + int ver_minor = Byte.toUnsignedInt(tlsRecord.get()); + int recLen = Short.toUnsignedInt(tlsRecord.getShort()); + + // Simple sanity checks + if (type != 22) { + throw new SSLException("Not a handshake: Type = " + type); + } else if (recLen > tlsRecord.remaining()) { + throw new SSLException("Incomplete record in buffer: " + + "Record length = " + recLen + ", Remaining = " + + tlsRecord.remaining()); + } + + while (tlsRecord.hasRemaining()) { + // Grab the handshake message header. + int msgHdr = tlsRecord.getInt(); + int msgType = (msgHdr >> 24) & 0x000000FF; + int msgLen = msgHdr & 0x00FFFFFF; + + if (msgType == TLS_HS_CERT_REQ) { + // Slice the buffer such that it contains the entire + // handshake message (less the handshake header). + int bufPos = tlsRecord.position(); + ByteBuffer buf = slice(tlsRecord, bufPos, msgLen); + + // Replace the signature scheme with an unknown value + twistSigSchemesCertReq(buf, (short) 0x0000); + byte[] bufBytes = new byte[buf.limit()]; + buf.get(bufBytes); + tlsRecord.position(bufPos).put(bufBytes); + + break; + } else { + // Skip to the next handshake message, if there is one + tlsRecord.position(tlsRecord.position() + msgLen); + } + } + + tlsRecord.reset(); + } + + /* Implementation of ByteBuffer.slice(int, int) for JDK11 */ + private static final ByteBuffer slice(ByteBuffer buffer, int index, int length) { + final int limit = buffer.limit(); + final int position = buffer.position(); + buffer.position(index); + buffer.limit(index + length); + ByteBuffer slice = buffer.slice(); + buffer.limit(limit); + buffer.position(position); + return slice; + } + + /** + * Replace the signature schemes in CertificateRequest message with an + * alternative value. It is assumed that the provided ByteBuffer has its + * position set at the first byte of the CertificateRequest message body + * (AFTER the handshake header) and contains the entire CR message. Upon + * successful completion of this method the ByteBuffer will have its + * position reset to the initial offset in the buffer. + * If an exception is thrown the position at the time of the exception + * will be preserved. + * + * @param data the ByteBuffer containing the CertificateRequest bytes + * @param altSigScheme an alternative signature scheme + */ + private static void twistSigSchemesCertReq(ByteBuffer data, + Short altSigScheme) { + Objects.requireNonNull(data); + data.mark(); + + // Jump past the certificate types + int certTypeLen = Byte.toUnsignedInt(data.get()); + if (certTypeLen != 0) { + data.position(data.position() + certTypeLen); + } + + int sigSchemeLen = Short.toUnsignedInt(data.getShort()); + for (int ssOff = 0; ssOff < sigSchemeLen; ssOff += 2) { + System.err.println( + "Use alternative signature scheme: " + altSigScheme); + data.putShort(data.position(), altSigScheme); + } + + data.reset(); + } +} diff --git a/test/jdk/sun/security/ssl/SignatureScheme/SigAlgosExtTestWithTLS13.java b/test/jdk/sun/security/ssl/SignatureScheme/SigAlgosExtTestWithTLS13.java new file mode 100644 index 000000000000..c4784c09da8e --- /dev/null +++ b/test/jdk/sun/security/ssl/SignatureScheme/SigAlgosExtTestWithTLS13.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2021, Tencent. 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 8263188 + * @summary If TLS the server and client has no common signature algorithms, + * the connection should fail fast with "No supported signature algorithm". + * This test only covers TLS 1.3, but doesn't cover client authentication. + * + * @library /test/lib + * /javax/net/ssl/templates + * + * @run main/othervm + * -Djdk.tls.server.SignatureSchemes=ecdsa_secp384r1_sha384 + * -Djdk.tls.client.SignatureSchemes=ecdsa_secp256r1_sha256,ecdsa_secp384r1_sha384 + * -Dtest.expectFail=false + * SigAlgosExtTestWithTLS13 + * @run main/othervm + * -Djdk.tls.server.SignatureSchemes=ecdsa_secp384r1_sha384 + * -Djdk.tls.client.SignatureSchemes=ecdsa_secp256r1_sha256 + * -Dtest.expectFail=true + * SigAlgosExtTestWithTLS13 + */ + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.SSLSocket; + +public class SigAlgosExtTestWithTLS13 extends SSLSocketTemplate { + + @Override + protected SSLContext createServerSSLContext() throws Exception { + return createSSLContext( + new Cert[] { Cert.CA_ECDSA_SECP256R1, Cert.CA_ECDSA_SECP384R1 }, + new Cert[] { Cert.EE_ECDSA_SECP256R1, Cert.EE_ECDSA_SECP384R1 }, + getServerContextParameters()); + } + + @Override + protected SSLContext createClientSSLContext() throws Exception { + return createSSLContext( + new Cert[] { Cert.CA_ECDSA_SECP256R1, Cert.CA_ECDSA_SECP384R1 }, + new Cert[] { Cert.EE_ECDSA_SECP256R1, Cert.EE_ECDSA_SECP384R1 }, + getClientContextParameters()); + } + + @Override + protected void configureClientSocket(SSLSocket socket) { + socket.setEnabledProtocols(new String[] { "TLSv1.3" }); + } + + public static void main(String[] args) throws Exception { + boolean expectFail = Boolean.getBoolean("test.expectFail"); + try { + new SigAlgosExtTestWithTLS13().run(); + if (expectFail) { + throw new RuntimeException( + "Expected SSLHandshakeException wasn't thrown"); + } + } catch (SSLHandshakeException e) { + if (expectFail && e.getMessage().equals( + "No supported signature algorithm")) { + System.out.println("Expected SSLHandshakeException"); + } else { + throw e; + } + } + } +} diff --git a/test/lib/jdk/test/lib/containers/cgroup/MetricsTesterCgroupV2.java b/test/lib/jdk/test/lib/containers/cgroup/MetricsTesterCgroupV2.java index a3723e2eda27..2a756102dede 100644 --- a/test/lib/jdk/test/lib/containers/cgroup/MetricsTesterCgroupV2.java +++ b/test/lib/jdk/test/lib/containers/cgroup/MetricsTesterCgroupV2.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Red Hat Inc. + * Copyright (c) 2025, 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 @@ -447,13 +448,13 @@ private void testIOStat() { Metrics metrics = Metrics.systemMetrics(); long oldVal = metrics.getBlkIOServiceCount(); long newVal = getIoStatAccumulate(new String[] { "rios", "wios" }); - if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { + if (newVal < oldVal) { fail("io.stat->rios/wios: ", oldVal, newVal); } oldVal = metrics.getBlkIOServiced(); newVal = getIoStatAccumulate(new String[] { "rbytes", "wbytes" }); - if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { + if (newVal < oldVal) { fail("io.stat->rbytes/wbytes: ", oldVal, newVal); } } diff --git a/test/lib/sun/hotspot/WhiteBox.java b/test/lib/sun/hotspot/WhiteBox.java index feae1ed8e2fb..cd97debd33b9 100644 --- a/test/lib/sun/hotspot/WhiteBox.java +++ b/test/lib/sun/hotspot/WhiteBox.java @@ -24,7 +24,11 @@ package sun.hotspot; import java.lang.management.MemoryUsage; +import java.lang.ref.Reference; import java.lang.reflect.Executable; +import java.lang.reflect.InaccessibleObjectException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; import java.util.function.BiFunction; @@ -405,6 +409,53 @@ public void clearInlineCaches(boolean preserve_static_stubs) { // always fail. public native boolean supportsConcurrentGCPhaseControl(); + // Infrastructure for waitForReferenceProcessing() + private static volatile Method waitForReferenceProcessingMethod = null; + + private static Method getWaitForReferenceProcessingMethod() { + Method wfrp = waitForReferenceProcessingMethod; + if (wfrp == null) { + try { + wfrp = Reference.class.getDeclaredMethod("waitForReferenceProcessing"); + wfrp.setAccessible(true); + assert wfrp.getReturnType() == Boolean.class; + Class[] ev = wfrp.getExceptionTypes(); + assert ev.length == 1; + assert ev[0] == InterruptedException.class; + waitForReferenceProcessingMethod = wfrp; + } catch (InaccessibleObjectException e) { + throw new RuntimeException("Need to add @modules java.base/java.lang.ref:open to test?", e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + return wfrp; + } + + /** + * Wait for reference processing, via Reference.waitForReferenceProcessing(). + * Callers of this method will need the + * @modules java.base/java.lang.ref:open + * jtreg tag. + * + * This method should usually be called after a call to WhiteBox.fullGC(). + */ + public boolean waitForReferenceProcessing() throws InterruptedException { + try { + Method wfrp = getWaitForReferenceProcessingMethod(); + return (Boolean) wfrp.invoke(null); + } catch (IllegalAccessException e) { + throw new RuntimeException("Shouldn't happen, we call setAccessible()", e); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof InterruptedException) { + throw (InterruptedException) cause; + } else { + throw new RuntimeException(e); + } + } + } + // Returns an array of concurrent phase names provided by this // collector. These are the names recognized by // requestConcurrentGCPhase().