diff options
author | 2023-10-26 18:55:37 +0100 | |
---|---|---|
committer | 2023-10-27 18:54:57 +0000 | |
commit | 2d8e6f955580b0bdffb347140bca32fb5c3ddc51 (patch) | |
tree | 557e0dd2e9185a3711b4ce57e5c799668ef2849b | |
parent | 0445189c916d3d641b9e7945a1125c455ca50ddf (diff) |
Dex verifier: Report error for invalid encoded array value
Bug: 308093262
Test: run fuzzer locally
Change-Id: If10485fe36f259fce490c69bb1af552b5fff333f
-rw-r--r-- | dexdump/dexdump.cc | 2 | ||||
-rw-r--r-- | libdexfile/dex/dex_file.cc | 14 | ||||
-rw-r--r-- | libdexfile/dex/dex_file.h | 8 | ||||
-rw-r--r-- | libdexfile/dex/dex_file_verifier.cc | 15 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.cc | 6 | ||||
-rw-r--r-- | tools/fuzzer/corpus/encoded_array_value.dex | bin | 0 -> 3428 bytes | |||
-rw-r--r-- | tools/fuzzer/corpus/encoded_array_value2.dex | bin | 0 -> 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 Binary files differnew file mode 100644 index 0000000000..3079f479e9 --- /dev/null +++ b/tools/fuzzer/corpus/encoded_array_value.dex diff --git a/tools/fuzzer/corpus/encoded_array_value2.dex b/tools/fuzzer/corpus/encoded_array_value2.dex Binary files differnew file mode 100644 index 0000000000..ed327cc997 --- /dev/null +++ b/tools/fuzzer/corpus/encoded_array_value2.dex |