in runtime/dex_file_verifier.cc [1327:1481]
bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t section_count,
uint16_t type) {
// Get the right alignment mask for the type of section.
size_t alignment_mask;
switch (type) {
case DexFile::kDexTypeClassDataItem:
case DexFile::kDexTypeStringDataItem:
case DexFile::kDexTypeDebugInfoItem:
case DexFile::kDexTypeAnnotationItem:
case DexFile::kDexTypeEncodedArrayItem:
alignment_mask = sizeof(uint8_t) - 1;
break;
default:
alignment_mask = sizeof(uint32_t) - 1;
break;
}
// Iterate through the items in the section.
for (uint32_t i = 0; i < section_count; i++) {
size_t aligned_offset = (offset + alignment_mask) & ~alignment_mask;
// Check the padding between items.
if (!CheckPadding(offset, aligned_offset)) {
return false;
}
// Check depending on the section type.
switch (type) {
case DexFile::kDexTypeStringIdItem: {
if (!CheckListSize(ptr_, 1, sizeof(DexFile::StringId), "string_ids")) {
return false;
}
ptr_ += sizeof(DexFile::StringId);
break;
}
case DexFile::kDexTypeTypeIdItem: {
if (!CheckListSize(ptr_, 1, sizeof(DexFile::TypeId), "type_ids")) {
return false;
}
ptr_ += sizeof(DexFile::TypeId);
break;
}
case DexFile::kDexTypeProtoIdItem: {
if (!CheckListSize(ptr_, 1, sizeof(DexFile::ProtoId), "proto_ids")) {
return false;
}
ptr_ += sizeof(DexFile::ProtoId);
break;
}
case DexFile::kDexTypeFieldIdItem: {
if (!CheckListSize(ptr_, 1, sizeof(DexFile::FieldId), "field_ids")) {
return false;
}
ptr_ += sizeof(DexFile::FieldId);
break;
}
case DexFile::kDexTypeMethodIdItem: {
if (!CheckListSize(ptr_, 1, sizeof(DexFile::MethodId), "method_ids")) {
return false;
}
ptr_ += sizeof(DexFile::MethodId);
break;
}
case DexFile::kDexTypeClassDefItem: {
if (!CheckListSize(ptr_, 1, sizeof(DexFile::ClassDef), "class_defs")) {
return false;
}
ptr_ += sizeof(DexFile::ClassDef);
break;
}
case DexFile::kDexTypeTypeList: {
if (!CheckList(sizeof(DexFile::TypeItem), "type_list", &ptr_)) {
return false;
}
break;
}
case DexFile::kDexTypeAnnotationSetRefList: {
if (!CheckList(sizeof(DexFile::AnnotationSetRefItem), "annotation_set_ref_list", &ptr_)) {
return false;
}
break;
}
case DexFile::kDexTypeAnnotationSetItem: {
if (!CheckList(sizeof(uint32_t), "annotation_set_item", &ptr_)) {
return false;
}
break;
}
case DexFile::kDexTypeClassDataItem: {
if (!CheckIntraClassDataItem()) {
return false;
}
break;
}
case DexFile::kDexTypeCodeItem: {
if (!CheckIntraCodeItem()) {
return false;
}
break;
}
case DexFile::kDexTypeStringDataItem: {
if (!CheckIntraStringDataItem()) {
return false;
}
break;
}
case DexFile::kDexTypeDebugInfoItem: {
if (!CheckIntraDebugInfoItem()) {
return false;
}
break;
}
case DexFile::kDexTypeAnnotationItem: {
if (!CheckIntraAnnotationItem()) {
return false;
}
break;
}
case DexFile::kDexTypeEncodedArrayItem: {
if (!CheckEncodedArray()) {
return false;
}
break;
}
case DexFile::kDexTypeAnnotationsDirectoryItem: {
if (!CheckIntraAnnotationsDirectoryItem()) {
return false;
}
break;
}
default:
ErrorStringPrintf("Unknown map item type %x", type);
return false;
}
if (IsDataSectionType(type)) {
if (aligned_offset == 0u) {
ErrorStringPrintf("Item %d offset is 0", i);
return false;
}
DCHECK(offset_to_type_map_.Find(aligned_offset) == offset_to_type_map_.end());
offset_to_type_map_.Insert(std::pair<uint32_t, uint16_t>(aligned_offset, type));
}
aligned_offset = ptr_ - begin_;
if (UNLIKELY(aligned_offset > size_)) {
ErrorStringPrintf("Item %d at ends out of bounds", i);
return false;
}
offset = aligned_offset;
}
return true;
}