Skip to content

Commit 71d9a83

Browse files
author
David Holmes
committed
8323243: JNI invocation of an abstract instance method corrupts the stack
Reviewed-by: coleenp, shade
1 parent d83ea92 commit 71d9a83

File tree

4 files changed

+159
-0
lines changed

4 files changed

+159
-0
lines changed

src/hotspot/share/prims/jni.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,11 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive
930930
}
931931
}
932932

933+
if (selected_method->is_abstract()) {
934+
ResourceMark rm(THREAD);
935+
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), selected_method->name()->as_C_string());
936+
}
937+
933938
methodHandle method(THREAD, selected_method);
934939

935940
// Create object to hold arguments for the JavaCall, and associate it with
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
/*
25+
* This is a non-abstract class with an abstract method.
26+
*
27+
*/
28+
super public class AbstractMethodClass
29+
extends java/lang/Object
30+
version 51:0 // Java 7 version
31+
{
32+
33+
public Method "<init>":"()V"
34+
stack 1 locals 1
35+
{
36+
aload_0;
37+
invokespecial Method java/lang/Object."<init>":"()V";
38+
return;
39+
}
40+
41+
public abstract Method "abstractM":"()V";
42+
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
25+
/*
26+
* @test
27+
* @bug 8323243
28+
* @summary Test that invocation of an abstract method from JNI works correctly
29+
* @compile AbstractMethodClass.jasm
30+
* @run main/othervm/native TestJNIAbstractMethod
31+
*/
32+
33+
/**
34+
* We are testing invocation of an abstract method from JNI - which should
35+
* simply result in throwning AbstractMethodError. To invoke an abstract method
36+
* we must have an instance method (as abstract static methods are illegal),
37+
* but instantiating an abstract class is also illegal at the Java language
38+
* level, so we have to use a custom jasm class that contains an abstract method
39+
* declaration, but which is not itself declared as an abstract class.
40+
*/
41+
public class TestJNIAbstractMethod {
42+
43+
// Invokes an abstract method from JNI and throws AbstractMethodError.
44+
private static native void invokeAbstractM(Class<?> AMclass,
45+
AbstractMethodClass receiver);
46+
47+
static {
48+
System.loadLibrary("JNIAbstractMethod");
49+
}
50+
51+
public static void main(String[] args) {
52+
AbstractMethodClass obj = new AbstractMethodClass();
53+
try {
54+
System.out.println("Attempting direct invocation via Java");
55+
obj.abstractM();
56+
throw new RuntimeException("Did not get AbstractMethodError from Java!");
57+
} catch (AbstractMethodError expected) {
58+
System.out.println("ok - got expected exception: " + expected);
59+
}
60+
try {
61+
System.out.println("Attempting direct invocation via JNI");
62+
invokeAbstractM(obj.getClass(), obj);
63+
throw new RuntimeException("Did not get AbstractMethodError from JNI!");
64+
} catch (AbstractMethodError expected) {
65+
System.out.println("ok - got expected exception: " + expected);
66+
}
67+
}
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
#include <jni.h>
25+
#include <stdio.h>
26+
#include <stdlib.h>
27+
28+
JNIEXPORT void JNICALL Java_TestJNIAbstractMethod_invokeAbstractM(JNIEnv* env,
29+
jclass this_cls,
30+
jclass target_cls,
31+
jobject receiver) {
32+
33+
jmethodID mid = (*env)->GetMethodID(env, target_cls, "abstractM", "()V");
34+
if (mid == NULL) {
35+
fprintf(stderr, "Error looking up method abstractM\n");
36+
(*env)->ExceptionDescribe(env);
37+
exit(1);
38+
}
39+
40+
printf("Invoking abstract method ...\n");
41+
(*env)->CallVoidMethod(env, receiver, mid); // Should raise exception
42+
43+
}

0 commit comments

Comments
 (0)