diff options
author | Dimitry Ivanov <dimitry@google.com> | 2016-07-14 18:12:59 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2016-07-14 18:12:59 +0000 |
commit | 51f64197ae5c3e0b83d87be78e591aad956348a1 (patch) | |
tree | 2959902b69e8c7c740f390c984185bc4e798e7cd | |
parent | 85f900d58902bc54ac3f6efc7240de0a576ba51c (diff) | |
parent | 0c9d30f3c83bb451412ad5fdda73529d661cb0fc (diff) | |
download | bionic-nougat-mr1-wear-release.tar.gz |
Merge "linker: Improve elf-file validation"android-wear-7.1.1_r1android-n-iot-preview-2nougat-mr1-wear-releasen-iot-preview-2
-rw-r--r-- | linker/linker_phdr.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp index 136e43236..4eff46d49 100644 --- a/linker/linker_phdr.cpp +++ b/linker/linker_phdr.cpp @@ -252,7 +252,12 @@ bool ElfReader::CheckFileRange(ElfW(Addr) offset, size_t size) { off64_t range_start; off64_t range_end; - return safe_add(&range_start, file_offset_, offset) && + // Only header can be located at the 0 offset... This function called to + // check DYNSYM and DYNAMIC sections and phdr/shdr - none of them can be + // and 0 offset. + + return offset > 0 && + safe_add(&range_start, file_offset_, offset) && safe_add(&range_end, range_start, size) && range_start < file_size_ && range_end <= file_size_; @@ -324,6 +329,35 @@ bool ElfReader::ReadDynamicSection() { return false; } + // Make sure dynamic_shdr offset and size matches PT_DYNAMIC phdr + size_t pt_dynamic_offset = 0; + size_t pt_dynamic_filesz = 0; + for (size_t i = 0; i < phdr_num_; ++i) { + const ElfW(Phdr)* phdr = &phdr_table_[i]; + if (phdr->p_type == PT_DYNAMIC) { + pt_dynamic_offset = phdr->p_offset; + pt_dynamic_filesz = phdr->p_filesz; + } + } + + if (pt_dynamic_offset != dynamic_shdr->sh_offset) { + DL_ERR("\"%s\" .dynamic section has invalid offset: 0x%zx, " + "expected to match PT_DYNAMIC offset: 0x%zx", + name_.c_str(), + static_cast<size_t>(dynamic_shdr->sh_offset), + pt_dynamic_offset); + return false; + } + + if (pt_dynamic_filesz != dynamic_shdr->sh_size) { + DL_ERR("\"%s\" .dynamic section has invalid size: 0x%zx, " + "expected to match PT_DYNAMIC filesz: 0x%zx", + name_.c_str(), + static_cast<size_t>(dynamic_shdr->sh_size), + pt_dynamic_filesz); + return false; + } + if (dynamic_shdr->sh_link >= shdr_num_) { DL_ERR("\"%s\" .dynamic section has invalid sh_link: %d", name_.c_str(), dynamic_shdr->sh_link); return false; |