Enabled access check for classes and methods in the verifier.
All checks should pass in frameworks. The only thing left in the
verifier is to tolerate classes/methods/fields that fail to resolve
initially.
Change-Id: I2afe0295bb16542259b2122a9056b3139d908871
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index ebb71b2..6ea276f 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -4366,7 +4366,6 @@
return NULL;
}
-#if 0
/* Check if access is allowed. */
if (!referrer->CanAccess(res_class)) {
LOG(ERROR) << "VFY: illegal class access: "
@@ -4375,7 +4374,6 @@
*failure = VERIFY_ERROR_ACCESS_CLASS;
return NULL;
}
-#endif
return res_class;
}
@@ -4414,9 +4412,8 @@
}
}
-#if 0
/* Check if access is allowed. */
- if (!referrer->CanAccess(res_method->GetDeclaringClass())) {
+ if (!referrer->CanAccessMember(res_method->GetDeclaringClass(), res_method->GetAccessFlags())) {
LOG(ERROR) << "VFY: illegal method access (call "
<< res_method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
<< "." << res_method->GetName()->ToModifiedUtf8() << " "
@@ -4425,7 +4422,6 @@
*failure = VERIFY_ERROR_ACCESS_METHOD;
return NULL;
}
-#endif
return res_method;
}
@@ -4467,7 +4463,7 @@
}
/* Check if access is allowed. */
- if (!referrer->CanAccess(res_field->GetDeclaringClass())) {
+ if (!referrer->CanAccessMember(res_field->GetDeclaringClass(), res_field->GetAccessFlags())) {
LOG(ERROR) << "VFY: access denied from "
<< referrer->GetDescriptor()->ToModifiedUtf8() << " to field "
<< res_field->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
diff --git a/src/object.cc b/src/object.cc
index 813abce..64607e8 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -1030,10 +1030,10 @@
return false;
}
// Arrays are in the same package when their element classes are.
- if (klass1->IsArrayClass()) {
+ while (klass1->IsArrayClass()) {
klass1 = klass1->GetComponentType();
}
- if (klass2->IsArrayClass()) {
+ while (klass2->IsArrayClass()) {
klass2 = klass2->GetComponentType();
}
// Compare the package part of the descriptor string.
diff --git a/src/object.h b/src/object.h
index 2ee90fc..63a2b30 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1501,6 +1501,35 @@
return that->IsPublic() || this->IsInSamePackage(that);
}
+ // Validate method/field access.
+ bool CanAccessMember(const Class* access_to, uint32_t member_flags) const {
+ // quick accept for public access
+ if (member_flags & kAccPublic) {
+ return true;
+ }
+
+ // quick accept for access from same class
+ if (this == access_to) {
+ return true;
+ }
+
+ // quick reject for private access from another class
+ if (member_flags & kAccPrivate) {
+ return false;
+ }
+
+ // Semi-quick test for protected access from a sub-class, which may or
+ // may not be in the same package.
+ if (member_flags & kAccProtected) {
+ if (this->IsSubClass(access_to)) {
+ return true;
+ }
+ }
+
+ // Allow protected and private access from other classes in the same package.
+ return this->IsInSamePackage(access_to);
+ }
+
bool IsSubClass(const Class* klass) const;
bool IsAssignableFrom(const Class* src) const {