aboutsummaryrefslogtreecommitdiff
path: root/vm/analysis/CodeVerify.c
diff options
context:
space:
mode:
authorAndy McFadden <fadden@android.com>2010-10-10 12:59:11 -0700
committerAndy McFadden <fadden@android.com>2010-10-10 14:04:42 -0700
commit5276cccb15b6ce0133c8107ff9ff013b4a176ef7 (patch)
tree35e08cd5f08f61894993b23d69b35028b61a70fb /vm/analysis/CodeVerify.c
parent9be25d09d24b3d6d0dd1a41c1c09471af4827687 (diff)
Verify method invocation type.
Dalvik provides five different ways to invoke a method (virtual, super, direct, static, interface). Using a virtual invoke instruction to call a direct method will not produce the desired results. This adds a test to the verifier that ensures the method targeted by an invocation instruction is of an appropriate kind. Bug 3082885. (cherry-pick from dalvik-dev) Change-Id: I3237cbefc7314f0b9d7557fc0bfd2b548ea30938
Diffstat (limited to 'vm/analysis/CodeVerify.c')
-rw-r--r--vm/analysis/CodeVerify.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/vm/analysis/CodeVerify.c b/vm/analysis/CodeVerify.c
index ef6872e62..a7d634eae 100644
--- a/vm/analysis/CodeVerify.c
+++ b/vm/analysis/CodeVerify.c
@@ -1002,6 +1002,24 @@ static RegType primSigCharToRegType(char sigChar)
}
/*
+ * See if the method matches the MethodType.
+ */
+static bool isCorrectInvokeKind(MethodType methodType, Method* resMethod)
+{
+ switch (methodType) {
+ case METHOD_DIRECT:
+ return dvmIsDirectMethod(resMethod);
+ case METHOD_STATIC:
+ return dvmIsStaticMethod(resMethod);
+ case METHOD_VIRTUAL:
+ case METHOD_INTERFACE:
+ return !dvmIsDirectMethod(resMethod);
+ default:
+ return false;
+ }
+}
+
+/*
* Verify the arguments to a method. We're executing in "method", making
* a call to the method reference in vB.
*
@@ -1060,10 +1078,9 @@ static Method* verifyInvocationArgs(const Method* meth, const RegType* insnRegs,
//char* curMethodDesc =
// dexProtoCopyMethodDescriptor(&meth->prototype);
- LOGI("Could not find method %s.%s, referenced from "
- "method %s.%s\n",
- dotMissingClass, methodName/*, methodDesc*/,
- dotMethClass, meth->name/*, curMethodDesc*/);
+ LOGI("Could not find method %s.%s, referenced from method %s.%s\n",
+ dotMissingClass, methodName/*, methodDesc*/,
+ dotMethClass, meth->name/*, curMethodDesc*/);
free(dotMissingClass);
free(dotMethClass);
@@ -1093,6 +1110,16 @@ static Method* verifyInvocationArgs(const Method* meth, const RegType* insnRegs,
}
/*
+ * See if the method type implied by the invoke instruction matches the
+ * access flags for the target method.
+ */
+ if (!isCorrectInvokeKind(methodType, resMethod)) {
+ LOG_VFY("VFY: invoke type does not match method type of %s.%s\n",
+ resMethod->clazz->descriptor, resMethod->name);
+ goto fail;
+ }
+
+ /*
* If we're using invoke-super(method), make sure that the executing
* method's class' superclass has a vtable entry for the target method.
*/