aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Ivanov <dimitry@google.com>2016-07-14 18:12:59 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2016-07-14 18:12:59 +0000
commit51f64197ae5c3e0b83d87be78e591aad956348a1 (patch)
tree2959902b69e8c7c740f390c984185bc4e798e7cd
parent85f900d58902bc54ac3f6efc7240de0a576ba51c (diff)
parent0c9d30f3c83bb451412ad5fdda73529d661cb0fc (diff)
downloadbionic-nougat-mr1-wear-release.tar.gz
-rw-r--r--linker/linker_phdr.cpp36
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;