Mercurial > hg > graal-jvmci-8
comparison src/share/vm/interpreter/linkResolver.cpp @ 24170:0b85ccd62409 jdk8u131-b01
8168699: Validate special case invocations
Reviewed-by: kevinw, vlivanov
author | coleenp |
---|---|
date | Tue, 13 Dec 2016 14:37:04 -0500 |
parents | 81bed6c76a89 |
children | 719853999215 |
comparison
equal
deleted
inserted
replaced
24169:5ee58c7d3938 | 24170:0b85ccd62409 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
911 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | 911 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
912 } | 912 } |
913 } | 913 } |
914 | 914 |
915 | 915 |
916 void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, | 916 void LinkResolver::resolve_special_call(CallInfo& result, Handle recv, KlassHandle resolved_klass, Symbol* method_name, |
917 Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { | 917 Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { |
918 methodHandle resolved_method; | 918 methodHandle resolved_method; |
919 linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); | 919 linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); |
920 runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK); | 920 runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, recv, check_access, CHECK); |
921 } | 921 } |
922 | 922 |
923 // throws linktime exceptions | 923 // throws linktime exceptions |
924 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass, | 924 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass, |
925 Symbol* method_name, Symbol* method_signature, | 925 Symbol* method_name, Symbol* method_signature, |
1014 } | 1014 } |
1015 } | 1015 } |
1016 | 1016 |
1017 // throws runtime exceptions | 1017 // throws runtime exceptions |
1018 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, | 1018 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, |
1019 KlassHandle current_klass, bool check_access, TRAPS) { | 1019 KlassHandle current_klass, Handle recv, bool check_access, TRAPS) { |
1020 | 1020 |
1021 // resolved method is selected method unless we have an old-style lookup | 1021 // resolved method is selected method unless we have an old-style lookup |
1022 // for a superclass method | 1022 // for a superclass method |
1023 // Invokespecial for a superinterface, resolved method is selected method, | 1023 // Invokespecial for a superinterface, resolved method is selected method, |
1024 // no checks for shadowing | 1024 // no checks for shadowing |
1025 methodHandle sel_method(THREAD, resolved_method()); | 1025 methodHandle sel_method(THREAD, resolved_method()); |
1026 | 1026 |
1027 if (check_access && | |
1028 // check if the method is not <init> | |
1029 resolved_method->name() != vmSymbols::object_initializer_name()) { | |
1030 | |
1027 // check if this is an old-style super call and do a new lookup if so | 1031 // check if this is an old-style super call and do a new lookup if so |
1028 { KlassHandle method_klass = KlassHandle(THREAD, | |
1029 resolved_method->method_holder()); | |
1030 | |
1031 if (check_access && | |
1032 // a) check if ACC_SUPER flag is set for the current class | 1032 // a) check if ACC_SUPER flag is set for the current class |
1033 (current_klass->is_super() || !AllowNonVirtualCalls) && | 1033 if ((current_klass->is_super() || !AllowNonVirtualCalls) && |
1034 // b) check if the class of the resolved_klass is a superclass | 1034 // b) check if the class of the resolved_klass is a superclass |
1035 // (not supertype in order to exclude interface classes) of the current class. | 1035 // (not supertype in order to exclude interface classes) of the current class. |
1036 // This check is not performed for super.invoke for interface methods | 1036 // This check is not performed for super.invoke for interface methods |
1037 // in super interfaces. | 1037 // in super interfaces. |
1038 current_klass->is_subclass_of(resolved_klass()) && | 1038 current_klass->is_subclass_of(resolved_klass()) && |
1039 current_klass() != resolved_klass() && | 1039 current_klass() != resolved_klass()) { |
1040 // c) check if the method is not <init> | |
1041 resolved_method->name() != vmSymbols::object_initializer_name()) { | |
1042 // Lookup super method | 1040 // Lookup super method |
1043 KlassHandle super_klass(THREAD, current_klass->super()); | 1041 KlassHandle super_klass(THREAD, current_klass->super()); |
1044 lookup_instance_method_in_klasses(sel_method, super_klass, | 1042 lookup_instance_method_in_klasses(sel_method, super_klass, |
1045 resolved_method->name(), | 1043 resolved_method->name(), |
1046 resolved_method->signature(), CHECK); | 1044 resolved_method->signature(), CHECK); |
1049 ResourceMark rm(THREAD); | 1047 ResourceMark rm(THREAD); |
1050 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | 1048 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
1051 Method::name_and_sig_as_C_string(resolved_klass(), | 1049 Method::name_and_sig_as_C_string(resolved_klass(), |
1052 resolved_method->name(), | 1050 resolved_method->name(), |
1053 resolved_method->signature())); | 1051 resolved_method->signature())); |
1052 } | |
1053 } | |
1054 | |
1055 // Check that the class of objectref (the receiver) is the current class or interface, | |
1056 // or a subtype of the current class or interface (the sender), otherwise invokespecial | |
1057 // throws IllegalAccessError. | |
1058 // The verifier checks that the sender is a subtype of the class in the I/MR operand. | |
1059 // The verifier also checks that the receiver is a subtype of the sender, if the sender is | |
1060 // a class. If the sender is an interface, the check has to be performed at runtime. | |
1061 InstanceKlass* sender = InstanceKlass::cast(current_klass()); | |
1062 sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender; | |
1063 if (sender->is_interface() && recv.not_null()) { | |
1064 Klass* receiver_klass = recv->klass(); | |
1065 if (!receiver_klass->is_subtype_of(sender)) { | |
1066 ResourceMark rm(THREAD); | |
1067 char buf[500]; | |
1068 jio_snprintf(buf, sizeof(buf), | |
1069 "Receiver class %s must be the current class or a subtype of interface %s", | |
1070 receiver_klass->name()->as_C_string(), | |
1071 sender->name()->as_C_string()); | |
1072 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), buf); | |
1054 } | 1073 } |
1055 } | 1074 } |
1056 } | 1075 } |
1057 | 1076 |
1058 // check if not static | 1077 // check if not static |
1477 Symbol* signature, | 1496 Symbol* signature, |
1478 KlassHandle current_klass, | 1497 KlassHandle current_klass, |
1479 bool check_access) { | 1498 bool check_access) { |
1480 EXCEPTION_MARK; | 1499 EXCEPTION_MARK; |
1481 CallInfo info; | 1500 CallInfo info; |
1482 resolve_special_call(info, resolved_klass, name, signature, current_klass, check_access, THREAD); | 1501 resolve_special_call(info, Handle(), resolved_klass, name, signature, current_klass, check_access, THREAD); |
1483 if (HAS_PENDING_EXCEPTION) { | 1502 if (HAS_PENDING_EXCEPTION) { |
1484 CLEAR_PENDING_EXCEPTION; | 1503 CLEAR_PENDING_EXCEPTION; |
1485 return methodHandle(); | 1504 return methodHandle(); |
1486 } | 1505 } |
1487 return info.selected_method(); | 1506 return info.selected_method(); |
1493 // ConstantPool entries | 1512 // ConstantPool entries |
1494 | 1513 |
1495 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) { | 1514 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) { |
1496 switch (byte) { | 1515 switch (byte) { |
1497 case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break; | 1516 case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break; |
1498 case Bytecodes::_invokespecial : resolve_invokespecial (result, pool, index, CHECK); break; | 1517 case Bytecodes::_invokespecial : resolve_invokespecial (result, recv, pool, index, CHECK); break; |
1499 case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break; | 1518 case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break; |
1500 case Bytecodes::_invokehandle : resolve_invokehandle (result, pool, index, CHECK); break; | 1519 case Bytecodes::_invokehandle : resolve_invokehandle (result, pool, index, CHECK); break; |
1501 case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break; | 1520 case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break; |
1502 case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break; | 1521 case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break; |
1503 } | 1522 } |
1524 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); | 1543 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); |
1525 resolve_static_call(result, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); | 1544 resolve_static_call(result, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); |
1526 } | 1545 } |
1527 | 1546 |
1528 | 1547 |
1529 void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { | 1548 void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) { |
1530 KlassHandle resolved_klass; | 1549 KlassHandle resolved_klass; |
1531 Symbol* method_name = NULL; | 1550 Symbol* method_name = NULL; |
1532 Symbol* method_signature = NULL; | 1551 Symbol* method_signature = NULL; |
1533 KlassHandle current_klass; | 1552 KlassHandle current_klass; |
1534 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); | 1553 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); |
1535 resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK); | 1554 resolve_special_call(result, recv, resolved_klass, method_name, method_signature, current_klass, true, CHECK); |
1536 } | 1555 } |
1537 | 1556 |
1538 | 1557 |
1539 void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv, | 1558 void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv, |
1540 constantPoolHandle pool, int index, | 1559 constantPoolHandle pool, int index, |