aports/community/openjdk-mandrel/jdk-17.0.10-compatibility_patch
Celeste 3c57986abe community/openjdk-mandrel: add upstream patch for JDK 17.0.10 compatibility
Fixes this error due to a change in JDK 17.0.10:

"Error: Substitution target for com.oracle.svm.core.jdk.Target_javax_crypto_JceSecurity_IdentityWrapper is invalid as inner class IdentityWrapper in javax.crypto.JceSecurity can not be found. Make sure that the inner class is present."
2024-05-15 03:53:46 +00:00

267 lines
12 KiB
Plaintext

Patch-Source: https://github.com/graalvm/mandrel/commit/cedccd02520a6d9888e9cb5b2f6b505fca79dd7a
--
From cedccd02520a6d9888e9cb5b2f6b505fca79dd7a Mon Sep 17 00:00:00 2001
From: Foivos Zakkak <fzakkak@redhat.com>
Date: Thu, 9 Nov 2023 11:10:10 +0200
Subject: [PATCH] Fix `javax.crypto.JceSecurity` substitutions in JDK >=
17.0.10
Closes https://github.com/graalvm/mandrel/issues/607
---
...eSecurityHasInnerClassIdentityWrapper.java | 41 +++++++++++++++++++
...urityHasInnerClassWeakIdentityWrapper.java | 41 +++++++++++++++++++
.../svm/core/jdk/SecuritySubstitutions.java | 36 ++++++++++++++--
.../svm/hosted/SecurityServicesFeature.java | 32 ++++++++++++++-
4 files changed, 145 insertions(+), 5 deletions(-)
create mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JceSecurityHasInnerClassIdentityWrapper.java
create mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JceSecurityHasInnerClassWeakIdentityWrapper.java
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JceSecurityHasInnerClassIdentityWrapper.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JceSecurityHasInnerClassIdentityWrapper.java
new file mode 100644
index 000000000000..393d47004794
--- /dev/null
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JceSecurityHasInnerClassIdentityWrapper.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package com.oracle.svm.core.jdk;
+
+import java.util.function.BooleanSupplier;
+
+public class JceSecurityHasInnerClassIdentityWrapper implements BooleanSupplier {
+
+ @Override
+ public boolean getAsBoolean() {
+ try {
+ Class.forName("javax.crypto.JceSecurity$IdentityWrapper");
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
+}
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JceSecurityHasInnerClassWeakIdentityWrapper.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JceSecurityHasInnerClassWeakIdentityWrapper.java
new file mode 100644
index 000000000000..40f5e8732eb7
--- /dev/null
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JceSecurityHasInnerClassWeakIdentityWrapper.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package com.oracle.svm.core.jdk;
+
+import java.util.function.BooleanSupplier;
+
+public class JceSecurityHasInnerClassWeakIdentityWrapper implements BooleanSupplier {
+
+ @Override
+ public boolean getAsBoolean() {
+ try {
+ Class.forName("javax.crypto.JceSecurity$WeakIdentityWrapper");
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
+}
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SecuritySubstitutions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SecuritySubstitutions.java
index f4fead83b3e7..d769996b731f 100644
--- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SecuritySubstitutions.java
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SecuritySubstitutions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -26,6 +26,7 @@
import static com.oracle.svm.core.snippets.KnownIntrinsics.readCallerStackPointer;
+import java.lang.ref.ReferenceQueue;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
@@ -43,6 +44,7 @@
import java.security.SecureRandom;
import java.util.List;
import java.util.Map;
+import java.util.function.BooleanSupplier;
import java.util.function.Predicate;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
@@ -317,10 +319,26 @@ static boolean isTrustedCryptoProvider(Provider provider) {
}
}
+final class QueueFieldPresent implements BooleanSupplier {
+ @Override
+ public boolean getAsBoolean() {
+ try {
+ Class<?> jceSecurity = Class.forName("javax.crypto.JceSecurity");
+ jceSecurity.getDeclaredField("queue");
+ return true;
+ } catch (ClassNotFoundException | NoSuchFieldException e) {
+ return false;
+ }
+ }
+}
+
@TargetClass(className = "javax.crypto.JceSecurity")
@SuppressWarnings({"unused"})
final class Target_javax_crypto_JceSecurity {
+ @Alias @TargetElement(onlyWith = QueueFieldPresent.class)//
+ public static ReferenceQueue<Object> queue;
+
/*
* Lazily recompute the RANDOM field at runtime. We cannot push the entire static initialization
* of JceSecurity to run time because we want the JceSecurity.verificationResults initialized at
@@ -393,8 +411,7 @@ public Object transform(Object receiver, Object originalValue) {
}
}
-@TargetClass(className = "javax.crypto.JceSecurity", innerClass = "IdentityWrapper", onlyWith = JDK17OrLater.class)
-@SuppressWarnings({"unused"})
+@TargetClass(className = "javax.crypto.JceSecurity", innerClass = "IdentityWrapper", onlyWith = JceSecurityHasInnerClassIdentityWrapper.class)
final class Target_javax_crypto_JceSecurity_IdentityWrapper {
@Alias //
Provider obj;
@@ -405,6 +422,14 @@ final class Target_javax_crypto_JceSecurity_IdentityWrapper {
}
}
+@TargetClass(className = "javax.crypto.JceSecurity", innerClass = "WeakIdentityWrapper", onlyWith = JceSecurityHasInnerClassWeakIdentityWrapper.class)
+final class Target_javax_crypto_JceSecurity_WeakIdentityWrapper {
+ @Alias //
+ Target_javax_crypto_JceSecurity_WeakIdentityWrapper(Provider obj, ReferenceQueue<Object> queue) {
+ // Do nothing this is just an alias
+ }
+}
+
class JceSecurityAccessor {
private static volatile SecureRandom RANDOM;
@@ -436,7 +461,12 @@ static Object providerKey(Provider p) {
if (JavaVersionUtil.JAVA_SPEC <= 11) {
return p;
}
+
/* Starting with JDK 17 the verification results map key is an identity wrapper object. */
+ if (new JceSecurityHasInnerClassWeakIdentityWrapper().getAsBoolean()) {
+ return new Target_javax_crypto_JceSecurity_WeakIdentityWrapper(p, Target_javax_crypto_JceSecurity.queue);
+ }
+
return new Target_javax_crypto_JceSecurity_IdentityWrapper(p);
}
diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java
index d5c4e9ea3dba..56e4790d7fbb 100644
--- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java
+++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 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
@@ -31,6 +31,7 @@
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.ref.Reference;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -87,6 +88,7 @@
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+import com.oracle.svm.core.jdk.JceSecurityHasInnerClassWeakIdentityWrapper;
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.nativeimage.ImageSingletons;
@@ -885,7 +887,33 @@ private Function<Object, Object> constructVerificationCacheCleaner(Class<?> jceS
};
}
/*
- * For JDK 17 and later, the verification cache is an IdentityWrapper -> Verification result
+ * For JDK 17.0.10 and later, the verification cache is a WeakIdentityWrapper ->
+ * Verification result ConcurrentHashMap. The WeakIdentityWrapper contains the actual
+ * provider in the 'obj' field.
+ */
+ if (new JceSecurityHasInnerClassWeakIdentityWrapper().getAsBoolean()) {
+ Method getReferent = ReflectionUtil.lookupMethod(Reference.class, "get");
+ Predicate<Object> listRemovalPredicate = wrapper -> {
+ try {
+ return shouldRemoveProvider((Provider) getReferent.invoke(wrapper));
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw VMError.shouldNotReachHere(e);
+ }
+ };
+
+ return obj -> {
+ Map<Object, Object> original = (Map<Object, Object>) obj;
+ Map<Object, Object> verificationResults = new ConcurrentHashMap<>(original);
+
+ verificationResults.keySet().removeIf(listRemovalPredicate);
+
+ return verificationResults;
+ };
+
+ }
+
+ /*
+ * For JDK 17 up to 17.0.10, the verification cache is an IdentityWrapper -> Verification result
* ConcurrentHashMap. The IdentityWrapper contains the actual provider in the 'obj' field.
*/
Class<?> identityWrapper = loader.findClassOrFail("javax.crypto.JceSecurity$IdentityWrapper");