aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.
*/