summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author David Srbecky <dsrbecky@google.com> 2023-10-26 18:55:37 +0100
committer Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2023-10-27 18:54:57 +0000
commit2d8e6f955580b0bdffb347140bca32fb5c3ddc51 (patch)
tree557e0dd2e9185a3711b4ce57e5c799668ef2849b
parent0445189c916d3d641b9e7945a1125c455ca50ddf (diff)
Dex verifier: Report error for invalid encoded array value
Bug: 308093262 Test: run fuzzer locally Change-Id: If10485fe36f259fce490c69bb1af552b5fff333f
-rw-r--r--dexdump/dexdump.cc2
-rw-r--r--libdexfile/dex/dex_file.cc14
-rw-r--r--libdexfile/dex/dex_file.h8
-rw-r--r--libdexfile/dex/dex_file_verifier.cc15
-rw-r--r--runtime/interpreter/interpreter_common.cc6
-rw-r--r--tools/fuzzer/corpus/encoded_array_value.dexbin0 -> 3428 bytes
-rw-r--r--tools/fuzzer/corpus/encoded_array_value2.dexbin0 -> 1864 bytes
7 files changed, 34 insertions, 11 deletions
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc
index 635734bcce..b237c0e4a8 100644
--- a/dexdump/dexdump.cc
+++ b/dexdump/dexdump.cc
@@ -1890,6 +1890,8 @@ static void dumpCallSite(const DexFile* pDexFile, u4 idx) {
type = "boolean";
value = it.GetJavaValue().z ? "true" : "false";
break;
+ case EncodedArrayValueIterator::ValueType::kEndOfInput:
+ UNREACHABLE();
}
if (gOptions.outputFormat == OUTPUT_PLAIN) {
diff --git a/libdexfile/dex/dex_file.cc b/libdexfile/dex/dex_file.cc
index 752c0d937a..b27855e5bb 100644
--- a/libdexfile/dex/dex_file.cc
+++ b/libdexfile/dex/dex_file.cc
@@ -673,14 +673,15 @@ EncodedArrayValueIterator::EncodedArrayValueIterator(const DexFile& dex_file,
type_(kByte) {
array_size_ = (ptr_ != nullptr) ? DecodeUnsignedLeb128(&ptr_) : 0;
if (array_size_ > 0) {
- Next();
+ bool ok [[maybe_unused]] = MaybeNext();
}
}
-void EncodedArrayValueIterator::Next() {
+bool EncodedArrayValueIterator::MaybeNext() {
pos_++;
if (pos_ >= array_size_) {
- return;
+ type_ = kEndOfInput;
+ return true;
}
uint8_t value_type = *ptr_++;
uint8_t value_arg = value_type >> kEncodedValueArgShift;
@@ -726,17 +727,16 @@ void EncodedArrayValueIterator::Next() {
case kEnum:
case kArray:
case kAnnotation:
- UNIMPLEMENTED(FATAL) << ": type " << type_;
- UNREACHABLE();
+ return false;
case kNull:
jval_.l = nullptr;
width = 0;
break;
default:
- LOG(FATAL) << "Unreached";
- UNREACHABLE();
+ return false;
}
ptr_ += width;
+ return true;
}
namespace dex {
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index 7deb6f806b..5068480001 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -994,7 +994,12 @@ class EncodedArrayValueIterator {
bool HasNext() const { return pos_ < array_size_; }
- void Next();
+ WARN_UNUSED bool MaybeNext();
+
+ ALWAYS_INLINE void Next() {
+ bool ok = MaybeNext();
+ DCHECK(ok) << "Unknown type: " << GetValueType();
+ }
enum ValueType {
kByte = 0x00,
@@ -1015,6 +1020,7 @@ class EncodedArrayValueIterator {
kAnnotation = 0x1d,
kNull = 0x1e,
kBoolean = 0x1f,
+ kEndOfInput = 0xff,
};
ValueType GetValueType() const { return type_; }
diff --git a/libdexfile/dex/dex_file_verifier.cc b/libdexfile/dex/dex_file_verifier.cc
index 2418794b45..0c07a30506 100644
--- a/libdexfile/dex/dex_file_verifier.cc
+++ b/libdexfile/dex/dex_file_verifier.cc
@@ -1230,7 +1230,10 @@ bool DexFileVerifier::CheckStaticFieldTypes(const dex::ClassDef& class_def) {
ErrorStringPrintf("unexpected static field initial value type: %x", array_type);
return false;
}
- array_it.Next();
+ if (!array_it.MaybeNext()) {
+ ErrorStringPrintf("unexpected encoded value type: '%c'", array_it.GetValueType());
+ return false;
+ }
}
if (array_it.HasNext()) {
@@ -2922,7 +2925,10 @@ bool DexFileVerifier::CheckInterCallSiteIdItem() {
}
// Check target method name.
- it.Next();
+ if (!it.MaybeNext()) {
+ ErrorStringPrintf("unexpected encoded value type: '%c'", it.GetValueType());
+ return false;
+ }
if (!it.HasNext() ||
it.GetValueType() != EncodedArrayValueIterator::ValueType::kString) {
ErrorStringPrintf("CallSiteArray missing target method name");
@@ -2936,7 +2942,10 @@ bool DexFileVerifier::CheckInterCallSiteIdItem() {
}
// Check method type.
- it.Next();
+ if (!it.MaybeNext()) {
+ ErrorStringPrintf("unexpected encoded value type: '%c'", it.GetValueType());
+ return false;
+ }
if (!it.HasNext() ||
it.GetValueType() != EncodedArrayValueIterator::ValueType::kMethodType) {
ErrorStringPrintf("CallSiteArray missing method type");
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 491f05fffd..28da3da3f7 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -607,6 +607,8 @@ static ObjPtr<mirror::Class> GetClassForBootstrapArgument(EncodedArrayValueItera
case EncodedArrayValueIterator::ValueType::kAnnotation:
case EncodedArrayValueIterator::ValueType::kNull:
return nullptr;
+ case EncodedArrayValueIterator::ValueType::kEndOfInput:
+ UNREACHABLE();
}
}
@@ -689,6 +691,8 @@ static bool GetArgumentForBootstrapMethod(Thread* self,
// determining the effect call site type based on the bootstrap
// argument types.
UNREACHABLE();
+ case EncodedArrayValueIterator::ValueType::kEndOfInput:
+ UNREACHABLE();
}
}
@@ -732,6 +736,8 @@ static bool PackArgumentForBootstrapMethod(Thread* self,
// determining the effect call site type based on the bootstrap
// argument types.
UNREACHABLE();
+ case EncodedArrayValueIterator::ValueType::kEndOfInput:
+ UNREACHABLE();
}
}
diff --git a/tools/fuzzer/corpus/encoded_array_value.dex b/tools/fuzzer/corpus/encoded_array_value.dex
new file mode 100644
index 0000000000..3079f479e9
--- /dev/null
+++ b/tools/fuzzer/corpus/encoded_array_value.dex
Binary files differ
diff --git a/tools/fuzzer/corpus/encoded_array_value2.dex b/tools/fuzzer/corpus/encoded_array_value2.dex
new file mode 100644
index 0000000000..ed327cc997
--- /dev/null
+++ b/tools/fuzzer/corpus/encoded_array_value2.dex
Binary files differ