1 Star 0 Fork 81

zhaosai/openjdk-1.8.0

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
8177146-MethodHandles.Lookup-bind-allows-illegal-pro.patch 10.37 KB
一键复制 编辑 原始数据 按行查看 历史
kuen 提交于 2024-01-18 15:17 . I8X6CH: upgrade to 8u402
From 5fbf4e8b326dd8453822ae40f3c6e4adffbf42ac Mon Sep 17 00:00:00 2001
From: zhangyipeng <zhangyipeng7@huawei.com>
Date: Fri, 3 Nov 2023 16:21:09 +0800
Subject: [PATCH] [Backport]8177146: MethodHandles.Lookup::bind allows illegal protected
access
---
.../classes/java/lang/invoke/MethodHandles.java | 22 +++--
.../lang/invoke/8177146/TestMethodHandleBind.java | 96 ++++++++++++++++++++++
jdk/test/java/lang/invoke/8177146/pkg/A.java | 40 +++++++++
3 files changed, 149 insertions(+), 9 deletions(-)
create mode 100644 jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java
create mode 100644 jdk/test/java/lang/invoke/8177146/pkg/A.java
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
index 7b9353ab0..62888c019 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
@@ -1148,7 +1148,13 @@ return mh1;
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
Class<? extends Object> refc = receiver.getClass(); // may get NPE
MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
- MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
+ MethodHandle mh = getDirectMethodNoRestrictInvokeSpecial(refc, method, findBoundCallerClass(method));
+ if (!mh.type().leadingReferenceParameter().isAssignableFrom(receiver.getClass())) {
+ throw new IllegalAccessException("The restricted defining class " +
+ mh.type().leadingReferenceParameter().getName() +
+ " is not assignable from receiver class " +
+ receiver.getClass().getName());
+ }
return mh.bindArgumentL(0, receiver).setVarargs(method);
}
@@ -1591,7 +1597,7 @@ return mh1;
throw method.makeAccessException("caller class must be a subclass below the method", caller);
}
MethodType rawType = mh.type();
- if (rawType.parameterType(0) == caller) return mh;
+ if (caller.isAssignableFrom(rawType.parameterType(0))) return mh; // no need to restrict; already narrow
MethodType narrowType = rawType.changeParameterType(0, caller);
assert(!mh.isVarargsCollector()); // viewAsType will lose varargs-ness
assert(mh.viewAsTypeChecks(narrowType, true));
@@ -1604,11 +1610,11 @@ return mh1;
final boolean checkSecurity = true;
return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
}
- /** Check access and get the requested method, eliding receiver narrowing rules. */
- private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
+ /** Check access and get the requested method, for invokespecial with no restriction on the application of narrowing rules. */
+ private MethodHandle getDirectMethodNoRestrictInvokeSpecial(Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
final boolean doRestrict = false;
final boolean checkSecurity = true;
- return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
+ return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerClass);
}
/** Check access and get the requested method, eliding security manager checks. */
private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
@@ -1660,10 +1666,8 @@ return mh1;
DirectMethodHandle dmh = DirectMethodHandle.make(refKind, refc, method);
MethodHandle mh = dmh;
// Optionally narrow the receiver argument to refc using restrictReceiver.
- if (doRestrict &&
- (refKind == REF_invokeSpecial ||
- (MethodHandleNatives.refKindHasReceiver(refKind) &&
- restrictProtectedReceiver(method)))) {
+ if ((doRestrict && refKind == REF_invokeSpecial) ||
+ (MethodHandleNatives.refKindHasReceiver(refKind) && restrictProtectedReceiver(method))) {
mh = restrictReceiver(method, dmh, lookupClass());
}
mh = maybeBindCaller(method, mh, callerClass);
diff --git a/jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java b/jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java
new file mode 100644
index 000000000..134cc9f75
--- /dev/null
+++ b/jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, 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 8177146
+ * @run testng/othervm TestMethodHandleBind
+ */
+
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+
+import static java.lang.invoke.MethodHandles.lookup;
+
+import static org.testng.Assert.*;
+
+public class TestMethodHandleBind extends pkg.A {
+ static class B extends TestMethodHandleBind {}
+
+ @Test
+ public void testInstanceOfCallerClass() throws Throwable {
+ MethodHandle bound = lookup().bind(new TestMethodHandleBind() , "m1", MethodType.methodType(String.class));
+ String x = (String)bound.invoke();
+ assertEquals(x, this.getClass().getSimpleName());
+ }
+
+ @Test
+ public void testInstanceOfCallerSubclass() throws Throwable {
+ MethodHandle bound = lookup().bind(new B() , "m1", MethodType.methodType(String.class));
+ // MethodHandle bound = lookup().findVirtual(B.class, "m1", MethodType.methodType(String.class)).bindTo(new B());
+ String x = (String)bound.invoke();
+ assertEquals(x, "B");
+ }
+
+ @Test
+ public void testInstanceOfReceiverClass() throws Throwable {
+ try {
+ MethodHandle bound = lookup().bind(new pkg.A() , "m1", MethodType.methodType(String.class));
+ bound.invoke();
+ fail("IllegalAccessException expected");
+ } catch (IllegalAccessException e) {
+ }
+ }
+
+ @Test
+ public void testPublicMethod() throws Throwable {
+ MethodHandle bound = lookup().bind(new pkg.A() , "m2", MethodType.methodType(String.class));
+ String x = (String)bound.invoke();
+ assertEquals(x, "A");
+ }
+
+ @Test
+ public void testPublicMethod2() throws Throwable {
+ MethodHandle bound = lookup().bind(new TestMethodHandleBind(), "m2", MethodType.methodType(String.class));
+ String x = (String)bound.invoke();
+ assertEquals(x, this.getClass().getSimpleName());
+ }
+
+ @Test
+ public void testInstanceOfCallerClassVarargs() throws Throwable {
+ MethodHandle bound = lookup().bind(new TestMethodHandleBind() , "m3", MethodType.methodType(String.class, String[].class));
+ String x = (String)bound.invoke("a", "b", "c");
+ assertEquals(x, this.getClass().getSimpleName() + "abc");
+ }
+
+ @Test
+ public void testInstanceOfReceiverClassVarargs() throws Throwable {
+ try {
+ MethodHandle bound = lookup().bind(new pkg.A(), "m3", MethodType.methodType(String.class, String[].class));
+ bound.invoke();
+ fail("IllegalAccessException expected");
+ } catch (IllegalAccessException e) {
+ }
+ }
+}
diff --git a/jdk/test/java/lang/invoke/8177146/pkg/A.java b/jdk/test/java/lang/invoke/8177146/pkg/A.java
new file mode 100644
index 000000000..f34d52b8e
--- /dev/null
+++ b/jdk/test/java/lang/invoke/8177146/pkg/A.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+package pkg;
+
+public class A {
+ protected String m1() {
+ return this.getClass().getSimpleName();
+ }
+
+ public String m2() {
+ return this.getClass().getSimpleName();
+ }
+
+ protected String m3(String... args) {
+ StringBuilder sb = new StringBuilder();
+ for (String s : args)
+ sb.append(s);
+ return this.getClass().getSimpleName() + sb.toString();
+ }
+}
--
2.12.3
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/zhaosai-Simon/openjdk-1.8.0.git
git@gitee.com:zhaosai-Simon/openjdk-1.8.0.git
zhaosai-Simon
openjdk-1.8.0
openjdk-1.8.0
master

搜索帮助