Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Side by Side Diff: courgette/disassembler_elf_32.cc

Issue 1031513002: Robust ELF header parsing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Replace uint32_t with Elf32_Off and add CHECK in ReduceLength Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « courgette/disassembler_elf_32.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "courgette/disassembler_elf_32.h" 5 #include "courgette/disassembler_elf_32.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 if (header_->e_machine != ElfEM()) 48 if (header_->e_machine != ElfEM())
49 return Bad("Not a supported architecture"); 49 return Bad("Not a supported architecture");
50 50
51 if (header_->e_version != 1) 51 if (header_->e_version != 1)
52 return Bad("Unknown file version"); 52 return Bad("Unknown file version");
53 53
54 if (header_->e_shentsize != sizeof(Elf32_Shdr)) 54 if (header_->e_shentsize != sizeof(Elf32_Shdr))
55 return Bad("Unexpected section header size"); 55 return Bad("Unexpected section header size");
56 56
57 if (header_->e_shoff >= length()) 57 if (!IsArrayInBounds(header_->e_shoff, header_->e_shnum, sizeof(Elf32_Shdr)))
58 return Bad("Out of bounds section header table offset"); 58 return Bad("Out of bounds section header table");
59 59
60 section_header_table_ = (Elf32_Shdr *)OffsetToPointer(header_->e_shoff); 60 section_header_table_ = (Elf32_Shdr *)OffsetToPointer(header_->e_shoff);
61 section_header_table_size_ = header_->e_shnum; 61 section_header_table_size_ = header_->e_shnum;
62 62
63 if ((header_->e_shoff + header_->e_shnum ) >= length()) 63 if (!IsArrayInBounds(header_->e_phoff, header_->e_phnum, sizeof(Elf32_Phdr)))
64 return Bad("Out of bounds section header table"); 64 return Bad("Out of bounds program header table");
65
66 if (header_->e_phoff >= length())
67 return Bad("Out of bounds program header table offset");
68 65
69 program_header_table_ = (Elf32_Phdr *)OffsetToPointer(header_->e_phoff); 66 program_header_table_ = (Elf32_Phdr *)OffsetToPointer(header_->e_phoff);
70 program_header_table_size_ = header_->e_phnum; 67 program_header_table_size_ = header_->e_phnum;
71 68
72 if ((header_->e_phoff + header_->e_phnum) >= length()) 69 if (header_->e_shstrndx >= header_->e_shnum)
73 return Bad("Out of bounds program header table"); 70 return Bad("Out of bounds string section index");
74 71
75 default_string_section_ = (const char *)SectionBody((int)header_->e_shstrndx); 72 default_string_section_ = (const char *)SectionBody((int)header_->e_shstrndx);
76 73
77 ReduceLength(DiscoverLength()); 74 if (!UpdateLength()) {
75 return Bad("Out of bounds section or segment");
76 }
78 77
79 return Good(); 78 return Good();
80 } 79 }
81 80
82 bool DisassemblerElf32::Disassemble(AssemblyProgram* target) { 81 bool DisassemblerElf32::Disassemble(AssemblyProgram* target) {
83 if (!ok()) 82 if (!ok())
84 return false; 83 return false;
85 84
86 // The Image Base is always 0 for ELF Executables 85 // The Image Base is always 0 for ELF Executables
87 target->set_image_base(0); 86 target->set_image_base(0);
88 87
89 if (!ParseAbs32Relocs()) 88 if (!ParseAbs32Relocs())
90 return false; 89 return false;
91 90
92 if (!ParseRel32RelocsFromSections()) 91 if (!ParseRel32RelocsFromSections())
93 return false; 92 return false;
94 93
95 if (!ParseFile(target)) 94 if (!ParseFile(target))
96 return false; 95 return false;
97 96
98 target->DefaultAssignIndexes(); 97 target->DefaultAssignIndexes();
99 98
100 return true; 99 return true;
101 } 100 }
102 101
103 uint32 DisassemblerElf32::DiscoverLength() { 102 bool DisassemblerElf32::UpdateLength() {
104 uint32 result = 0; 103 Elf32_Off result = 0;
105 104
106 // Find the end of the last section 105 // Find the end of the last section
107 for (int section_id = 0; section_id < SectionHeaderCount(); section_id++) { 106 for (int section_id = 0; section_id < SectionHeaderCount(); section_id++) {
108 const Elf32_Shdr *section_header = SectionHeader(section_id); 107 const Elf32_Shdr *section_header = SectionHeader(section_id);
109 108
110 if (section_header->sh_type == SHT_NOBITS) 109 if (section_header->sh_type == SHT_NOBITS)
111 continue; 110 continue;
112 111
113 uint32 section_end = section_header->sh_offset + section_header->sh_size; 112 if (!IsArrayInBounds(section_header->sh_offset, section_header->sh_size, 1))
113 return false;
114 114
115 if (section_end > result) 115 Elf32_Off section_end = section_header->sh_offset + section_header->sh_size;
116 result = section_end; 116 result = std::max(result, section_end);
117 } 117 }
118 118
119 // Find the end of the last segment 119 // Find the end of the last segment
120 for (int i = 0; i < ProgramSegmentHeaderCount(); i++) { 120 for (int i = 0; i < ProgramSegmentHeaderCount(); i++) {
121 const Elf32_Phdr *segment_header = ProgramSegmentHeader(i); 121 const Elf32_Phdr *segment_header = ProgramSegmentHeader(i);
122 122
123 uint32 segment_end = segment_header->p_offset + segment_header->p_filesz; 123 if (!IsArrayInBounds(segment_header->p_offset, segment_header->p_filesz, 1))
124 return false;
124 125
125 if (segment_end > result) 126 Elf32_Off segment_end = segment_header->p_offset + segment_header->p_filesz;
126 result = segment_end; 127 result = std::max(result, segment_end);
127 } 128 }
128 129
129 uint32 section_table_end = header_->e_shoff + 130 Elf32_Off section_table_end = header_->e_shoff +
130 (header_->e_shnum * sizeof(Elf32_Shdr)); 131 (header_->e_shnum * sizeof(Elf32_Shdr));
131 if (section_table_end > result) 132 result = std::max(result, section_table_end);
132 result = section_table_end;
133 133
134 uint32 segment_table_end = header_->e_phoff + 134 Elf32_Off segment_table_end = header_->e_phoff +
135 (header_->e_phnum * sizeof(Elf32_Phdr)); 135 (header_->e_phnum * sizeof(Elf32_Phdr));
136 if (segment_table_end > result) 136 result = std::max(result, segment_table_end);
137 result = segment_table_end;
138 137
139 return result; 138 ReduceLength(result);
139 return true;
140 } 140 }
141 141
142 CheckBool DisassemblerElf32::IsValidRVA(RVA rva) const { 142 CheckBool DisassemblerElf32::IsValidRVA(RVA rva) const {
143 143
144 // It's valid if it's contained in any program segment 144 // It's valid if it's contained in any program segment
145 for (int i = 0; i < ProgramSegmentHeaderCount(); i++) { 145 for (int i = 0; i < ProgramSegmentHeaderCount(); i++) {
146 const Elf32_Phdr *segment_header = ProgramSegmentHeader(i); 146 const Elf32_Phdr *segment_header = ProgramSegmentHeader(i);
147 147
148 if (segment_header->p_type != PT_LOAD) 148 if (segment_header->p_type != PT_LOAD)
149 continue; 149 continue;
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 return false; 494 return false;
495 } 495 }
496 496
497 std::sort(rel32_locations_.begin(), 497 std::sort(rel32_locations_.begin(),
498 rel32_locations_.end(), 498 rel32_locations_.end(),
499 TypedRVA::IsLessThan); 499 TypedRVA::IsLessThan);
500 return true; 500 return true;
501 } 501 }
502 502
503 } // namespace courgette 503 } // namespace courgette
OLDNEW
« no previous file with comments | « courgette/disassembler_elf_32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698