1 /*
2 * Copyright (C) 2012 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include "linker_phdr.h"
30
31 #include <errno.h>
32 #include <string.h>
33 #include <sys/mman.h>
34 #include <sys/prctl.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <unistd.h>
38
39 #include "linker.h"
40 #include "linker_dlwarning.h"
41 #include "linker_globals.h"
42 #include "linker_debug.h"
43 #include "linker_utils.h"
44
45 #include "private/CFIShadow.h" // For kLibraryAlignment
46
GetTargetElfMachine()47 static int GetTargetElfMachine() {
48 #if defined(__arm__)
49 return EM_ARM;
50 #elif defined(__aarch64__)
51 return EM_AARCH64;
52 #elif defined(__i386__)
53 return EM_386;
54 #elif defined(__riscv)
55 return EM_RISCV;
56 #elif defined(__x86_64__)
57 return EM_X86_64;
58 #endif
59 }
60
61 /**
62 TECHNICAL NOTE ON ELF LOADING.
63
64 An ELF file's program header table contains one or more PT_LOAD
65 segments, which corresponds to portions of the file that need to
66 be mapped into the process' address space.
67
68 Each loadable segment has the following important properties:
69
70 p_offset -> segment file offset
71 p_filesz -> segment file size
72 p_memsz -> segment memory size (always >= p_filesz)
73 p_vaddr -> segment's virtual address
74 p_flags -> segment flags (e.g. readable, writable, executable)
75 p_align -> segment's in-memory and in-file alignment
76
77 We will ignore the p_paddr field of ElfW(Phdr) for now.
78
79 The loadable segments can be seen as a list of [p_vaddr ... p_vaddr+p_memsz)
80 ranges of virtual addresses. A few rules apply:
81
82 - the virtual address ranges should not overlap.
83
84 - if a segment's p_filesz is smaller than its p_memsz, the extra bytes
85 between them should always be initialized to 0.
86
87 - ranges do not necessarily start or end at page boundaries. Two distinct
88 segments can have their start and end on the same page. In this case, the
89 page inherits the mapping flags of the latter segment.
90
91 Finally, the real load addrs of each segment is not p_vaddr. Instead the
92 loader decides where to load the first segment, then will load all others
93 relative to the first one to respect the initial range layout.
94
95 For example, consider the following list:
96
97 [ offset:0, filesz:0x4000, memsz:0x4000, vaddr:0x30000 ],
98 [ offset:0x4000, filesz:0x2000, memsz:0x8000, vaddr:0x40000 ],
99
100 This corresponds to two segments that cover these virtual address ranges:
101
102 0x30000...0x34000
103 0x40000...0x48000
104
105 If the loader decides to load the first segment at address 0xa0000000
106 then the segments' load address ranges will be:
107
108 0xa0030000...0xa0034000
109 0xa0040000...0xa0048000
110
111 In other words, all segments must be loaded at an address that has the same
112 constant offset from their p_vaddr value. This offset is computed as the
113 difference between the first segment's load address, and its p_vaddr value.
114
115 However, in practice, segments do _not_ start at page boundaries. Since we
116 can only memory-map at page boundaries, this means that the bias is
117 computed as:
118
119 load_bias = phdr0_load_address - PAGE_START(phdr0->p_vaddr)
120
121 (NOTE: The value must be used as a 32-bit unsigned integer, to deal with
122 possible wrap around UINT32_MAX for possible large p_vaddr values).
123
124 And that the phdr0_load_address must start at a page boundary, with
125 the segment's real content starting at:
126
127 phdr0_load_address + PAGE_OFFSET(phdr0->p_vaddr)
128
129 Note that ELF requires the following condition to make the mmap()-ing work:
130
131 PAGE_OFFSET(phdr0->p_vaddr) == PAGE_OFFSET(phdr0->p_offset)
132
133 The load_bias must be added to any p_vaddr value read from the ELF file to
134 determine the corresponding memory address.
135
136 **/
137
138 #define MAYBE_MAP_FLAG(x, from, to) (((x) & (from)) ? (to) : 0)
139 #define PFLAGS_TO_PROT(x) (MAYBE_MAP_FLAG((x), PF_X, PROT_EXEC) | \
140 MAYBE_MAP_FLAG((x), PF_R, PROT_READ) | \
141 MAYBE_MAP_FLAG((x), PF_W, PROT_WRITE))
142
143 // Default PMD size for x86_64 and aarch64 (2MB).
144 static constexpr size_t kPmdSize = (1UL << 21);
145
ElfReader()146 ElfReader::ElfReader()
147 : did_read_(false), did_load_(false), fd_(-1), file_offset_(0), file_size_(0), phdr_num_(0),
148 phdr_table_(nullptr), shdr_table_(nullptr), shdr_num_(0), dynamic_(nullptr), strtab_(nullptr),
149 strtab_size_(0), load_start_(nullptr), load_size_(0), load_bias_(0), loaded_phdr_(nullptr),
150 mapped_by_caller_(false) {
151 }
152
Read(const char * name,int fd,off64_t file_offset,off64_t file_size)153 bool ElfReader::Read(const char* name, int fd, off64_t file_offset, off64_t file_size) {
154 if (did_read_) {
155 return true;
156 }
157 name_ = name;
158 fd_ = fd;
159 file_offset_ = file_offset;
160 file_size_ = file_size;
161
162 if (ReadElfHeader() &&
163 VerifyElfHeader() &&
164 ReadProgramHeaders() &&
165 ReadSectionHeaders() &&
166 ReadDynamicSection()) {
167 did_read_ = true;
168 }
169
170 return did_read_;
171 }
172
Load(address_space_params * address_space)173 bool ElfReader::Load(address_space_params* address_space) {
174 CHECK(did_read_);
175 if (did_load_) {
176 return true;
177 }
178 bool reserveSuccess = ReserveAddressSpace(address_space);
179 if (reserveSuccess && LoadSegments() && FindPhdr() &&
180 FindGnuPropertySection()) {
181 did_load_ = true;
182 #if defined(__aarch64__)
183 // For Armv8.5-A loaded executable segments may require PROT_BTI.
184 if (note_gnu_property_.IsBTICompatible()) {
185 did_load_ = (phdr_table_protect_segments(phdr_table_, phdr_num_, load_bias_,
186 ¬e_gnu_property_) == 0);
187 }
188 #endif
189 }
190 if (reserveSuccess && !did_load_) {
191 if (load_start_ != nullptr && load_size_ != 0) {
192 if (!mapped_by_caller_) {
193 munmap(load_start_, load_size_);
194 }
195 }
196 }
197
198 return did_load_;
199 }
200
get_string(ElfW (Word)index) const201 const char* ElfReader::get_string(ElfW(Word) index) const {
202 CHECK(strtab_ != nullptr);
203 CHECK(index < strtab_size_);
204
205 return strtab_ + index;
206 }
207
ReadElfHeader()208 bool ElfReader::ReadElfHeader() {
209 ssize_t rc = TEMP_FAILURE_RETRY(pread64(fd_, &header_, sizeof(header_), file_offset_));
210 if (rc < 0) {
211 DL_ERR("can't read file \"%s\": %s", name_.c_str(), strerror(errno));
212 return false;
213 }
214
215 if (rc != sizeof(header_)) {
216 DL_ERR("\"%s\" is too small to be an ELF executable: only found %zd bytes", name_.c_str(),
217 static_cast<size_t>(rc));
218 return false;
219 }
220 return true;
221 }
222
EM_to_string(int em)223 static const char* EM_to_string(int em) {
224 if (em == EM_386) return "EM_386";
225 if (em == EM_AARCH64) return "EM_AARCH64";
226 if (em == EM_ARM) return "EM_ARM";
227 if (em == EM_RISCV) return "EM_RISCV";
228 if (em == EM_X86_64) return "EM_X86_64";
229 return "EM_???";
230 }
231
VerifyElfHeader()232 bool ElfReader::VerifyElfHeader() {
233 if (memcmp(header_.e_ident, ELFMAG, SELFMAG) != 0) {
234 DL_ERR("\"%s\" has bad ELF magic: %02x%02x%02x%02x", name_.c_str(),
235 header_.e_ident[0], header_.e_ident[1], header_.e_ident[2], header_.e_ident[3]);
236 return false;
237 }
238
239 // Try to give a clear diagnostic for ELF class mismatches, since they're
240 // an easy mistake to make during the 32-bit/64-bit transition period.
241 int elf_class = header_.e_ident[EI_CLASS];
242 #if defined(__LP64__)
243 if (elf_class != ELFCLASS64) {
244 if (elf_class == ELFCLASS32) {
245 DL_ERR("\"%s\" is 32-bit instead of 64-bit", name_.c_str());
246 } else {
247 DL_ERR("\"%s\" has unknown ELF class: %d", name_.c_str(), elf_class);
248 }
249 return false;
250 }
251 #else
252 if (elf_class != ELFCLASS32) {
253 if (elf_class == ELFCLASS64) {
254 DL_ERR("\"%s\" is 64-bit instead of 32-bit", name_.c_str());
255 } else {
256 DL_ERR("\"%s\" has unknown ELF class: %d", name_.c_str(), elf_class);
257 }
258 return false;
259 }
260 #endif
261
262 if (header_.e_ident[EI_DATA] != ELFDATA2LSB) {
263 DL_ERR("\"%s\" not little-endian: %d", name_.c_str(), header_.e_ident[EI_DATA]);
264 return false;
265 }
266
267 if (header_.e_type != ET_DYN) {
268 DL_ERR("\"%s\" has unexpected e_type: %d", name_.c_str(), header_.e_type);
269 return false;
270 }
271
272 if (header_.e_version != EV_CURRENT) {
273 DL_ERR("\"%s\" has unexpected e_version: %d", name_.c_str(), header_.e_version);
274 return false;
275 }
276
277 if (header_.e_machine != GetTargetElfMachine()) {
278 DL_ERR("\"%s\" is for %s (%d) instead of %s (%d)",
279 name_.c_str(),
280 EM_to_string(header_.e_machine), header_.e_machine,
281 EM_to_string(GetTargetElfMachine()), GetTargetElfMachine());
282 return false;
283 }
284
285 if (header_.e_shentsize != sizeof(ElfW(Shdr))) {
286 // Fail if app is targeting Android O or above
287 if (get_application_target_sdk_version() >= 26) {
288 DL_ERR_AND_LOG("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)",
289 name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
290 return false;
291 }
292 DL_WARN_documented_change(26,
293 "invalid-elf-header_section-headers-enforced-for-api-level-26",
294 "\"%s\" has unsupported e_shentsize 0x%x (expected 0x%zx)",
295 name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
296 add_dlwarning(name_.c_str(), "has invalid ELF header");
297 }
298
299 if (header_.e_shstrndx == 0) {
300 // Fail if app is targeting Android O or above
301 if (get_application_target_sdk_version() >= 26) {
302 DL_ERR_AND_LOG("\"%s\" has invalid e_shstrndx", name_.c_str());
303 return false;
304 }
305
306 DL_WARN_documented_change(26,
307 "invalid-elf-header_section-headers-enforced-for-api-level-26",
308 "\"%s\" has invalid e_shstrndx", name_.c_str());
309 add_dlwarning(name_.c_str(), "has invalid ELF header");
310 }
311
312 return true;
313 }
314
CheckFileRange(ElfW (Addr)offset,size_t size,size_t alignment)315 bool ElfReader::CheckFileRange(ElfW(Addr) offset, size_t size, size_t alignment) {
316 off64_t range_start;
317 off64_t range_end;
318
319 // Only header can be located at the 0 offset... This function called to
320 // check DYNSYM and DYNAMIC sections and phdr/shdr - none of them can be
321 // at offset 0.
322
323 return offset > 0 &&
324 safe_add(&range_start, file_offset_, offset) &&
325 safe_add(&range_end, range_start, size) &&
326 (range_start < file_size_) &&
327 (range_end <= file_size_) &&
328 ((offset % alignment) == 0);
329 }
330
331 // Loads the program header table from an ELF file into a read-only private
332 // anonymous mmap-ed block.
ReadProgramHeaders()333 bool ElfReader::ReadProgramHeaders() {
334 phdr_num_ = header_.e_phnum;
335
336 // Like the kernel, we only accept program header tables that
337 // are smaller than 64KiB.
338 if (phdr_num_ < 1 || phdr_num_ > 65536/sizeof(ElfW(Phdr))) {
339 DL_ERR("\"%s\" has invalid e_phnum: %zd", name_.c_str(), phdr_num_);
340 return false;
341 }
342
343 // Boundary checks
344 size_t size = phdr_num_ * sizeof(ElfW(Phdr));
345 if (!CheckFileRange(header_.e_phoff, size, alignof(ElfW(Phdr)))) {
346 DL_ERR_AND_LOG("\"%s\" has invalid phdr offset/size: %zu/%zu",
347 name_.c_str(),
348 static_cast<size_t>(header_.e_phoff),
349 size);
350 return false;
351 }
352
353 if (!phdr_fragment_.Map(fd_, file_offset_, header_.e_phoff, size)) {
354 DL_ERR("\"%s\" phdr mmap failed: %s", name_.c_str(), strerror(errno));
355 return false;
356 }
357
358 phdr_table_ = static_cast<ElfW(Phdr)*>(phdr_fragment_.data());
359 return true;
360 }
361
ReadSectionHeaders()362 bool ElfReader::ReadSectionHeaders() {
363 shdr_num_ = header_.e_shnum;
364
365 if (shdr_num_ == 0) {
366 DL_ERR_AND_LOG("\"%s\" has no section headers", name_.c_str());
367 return false;
368 }
369
370 size_t size = shdr_num_ * sizeof(ElfW(Shdr));
371 if (!CheckFileRange(header_.e_shoff, size, alignof(const ElfW(Shdr)))) {
372 DL_ERR_AND_LOG("\"%s\" has invalid shdr offset/size: %zu/%zu",
373 name_.c_str(),
374 static_cast<size_t>(header_.e_shoff),
375 size);
376 return false;
377 }
378
379 if (!shdr_fragment_.Map(fd_, file_offset_, header_.e_shoff, size)) {
380 DL_ERR("\"%s\" shdr mmap failed: %s", name_.c_str(), strerror(errno));
381 return false;
382 }
383
384 shdr_table_ = static_cast<const ElfW(Shdr)*>(shdr_fragment_.data());
385 return true;
386 }
387
ReadDynamicSection()388 bool ElfReader::ReadDynamicSection() {
389 // 1. Find .dynamic section (in section headers)
390 const ElfW(Shdr)* dynamic_shdr = nullptr;
391 for (size_t i = 0; i < shdr_num_; ++i) {
392 if (shdr_table_[i].sh_type == SHT_DYNAMIC) {
393 dynamic_shdr = &shdr_table_ [i];
394 break;
395 }
396 }
397
398 if (dynamic_shdr == nullptr) {
399 DL_ERR_AND_LOG("\"%s\" .dynamic section header was not found", name_.c_str());
400 return false;
401 }
402
403 // Make sure dynamic_shdr offset and size matches PT_DYNAMIC phdr
404 size_t pt_dynamic_offset = 0;
405 size_t pt_dynamic_filesz = 0;
406 for (size_t i = 0; i < phdr_num_; ++i) {
407 const ElfW(Phdr)* phdr = &phdr_table_[i];
408 if (phdr->p_type == PT_DYNAMIC) {
409 pt_dynamic_offset = phdr->p_offset;
410 pt_dynamic_filesz = phdr->p_filesz;
411 }
412 }
413
414 if (pt_dynamic_offset != dynamic_shdr->sh_offset) {
415 if (get_application_target_sdk_version() >= 26) {
416 DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid offset: 0x%zx, "
417 "expected to match PT_DYNAMIC offset: 0x%zx",
418 name_.c_str(),
419 static_cast<size_t>(dynamic_shdr->sh_offset),
420 pt_dynamic_offset);
421 return false;
422 }
423 DL_WARN_documented_change(26,
424 "invalid-elf-header_section-headers-enforced-for-api-level-26",
425 "\"%s\" .dynamic section has invalid offset: 0x%zx "
426 "(expected to match PT_DYNAMIC offset 0x%zx)",
427 name_.c_str(),
428 static_cast<size_t>(dynamic_shdr->sh_offset),
429 pt_dynamic_offset);
430 add_dlwarning(name_.c_str(), "invalid .dynamic section");
431 }
432
433 if (pt_dynamic_filesz != dynamic_shdr->sh_size) {
434 if (get_application_target_sdk_version() >= 26) {
435 DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid size: 0x%zx, "
436 "expected to match PT_DYNAMIC filesz: 0x%zx",
437 name_.c_str(),
438 static_cast<size_t>(dynamic_shdr->sh_size),
439 pt_dynamic_filesz);
440 return false;
441 }
442 DL_WARN_documented_change(26,
443 "invalid-elf-header_section-headers-enforced-for-api-level-26",
444 "\"%s\" .dynamic section has invalid size: 0x%zx "
445 "(expected to match PT_DYNAMIC filesz 0x%zx)",
446 name_.c_str(),
447 static_cast<size_t>(dynamic_shdr->sh_size),
448 pt_dynamic_filesz);
449 add_dlwarning(name_.c_str(), "invalid .dynamic section");
450 }
451
452 if (dynamic_shdr->sh_link >= shdr_num_) {
453 DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid sh_link: %d",
454 name_.c_str(),
455 dynamic_shdr->sh_link);
456 return false;
457 }
458
459 const ElfW(Shdr)* strtab_shdr = &shdr_table_[dynamic_shdr->sh_link];
460
461 if (strtab_shdr->sh_type != SHT_STRTAB) {
462 DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid link(%d) sh_type: %d (expected SHT_STRTAB)",
463 name_.c_str(), dynamic_shdr->sh_link, strtab_shdr->sh_type);
464 return false;
465 }
466
467 if (!CheckFileRange(dynamic_shdr->sh_offset, dynamic_shdr->sh_size, alignof(const ElfW(Dyn)))) {
468 DL_ERR_AND_LOG("\"%s\" has invalid offset/size of .dynamic section", name_.c_str());
469 return false;
470 }
471
472 if (!dynamic_fragment_.Map(fd_, file_offset_, dynamic_shdr->sh_offset, dynamic_shdr->sh_size)) {
473 DL_ERR("\"%s\" dynamic section mmap failed: %s", name_.c_str(), strerror(errno));
474 return false;
475 }
476
477 dynamic_ = static_cast<const ElfW(Dyn)*>(dynamic_fragment_.data());
478
479 if (!CheckFileRange(strtab_shdr->sh_offset, strtab_shdr->sh_size, alignof(const char))) {
480 DL_ERR_AND_LOG("\"%s\" has invalid offset/size of the .strtab section linked from .dynamic section",
481 name_.c_str());
482 return false;
483 }
484
485 if (!strtab_fragment_.Map(fd_, file_offset_, strtab_shdr->sh_offset, strtab_shdr->sh_size)) {
486 DL_ERR("\"%s\" strtab section mmap failed: %s", name_.c_str(), strerror(errno));
487 return false;
488 }
489
490 strtab_ = static_cast<const char*>(strtab_fragment_.data());
491 strtab_size_ = strtab_fragment_.size();
492 return true;
493 }
494
495 /* Returns the size of the extent of all the possibly non-contiguous
496 * loadable segments in an ELF program header table. This corresponds
497 * to the page-aligned size in bytes that needs to be reserved in the
498 * process' address space. If there are no loadable segments, 0 is
499 * returned.
500 *
501 * If out_min_vaddr or out_max_vaddr are not null, they will be
502 * set to the minimum and maximum addresses of pages to be reserved,
503 * or 0 if there is nothing to load.
504 */
phdr_table_get_load_size(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)* out_min_vaddr,ElfW (Addr)* out_max_vaddr)505 size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count,
506 ElfW(Addr)* out_min_vaddr,
507 ElfW(Addr)* out_max_vaddr) {
508 ElfW(Addr) min_vaddr = UINTPTR_MAX;
509 ElfW(Addr) max_vaddr = 0;
510
511 bool found_pt_load = false;
512 for (size_t i = 0; i < phdr_count; ++i) {
513 const ElfW(Phdr)* phdr = &phdr_table[i];
514
515 if (phdr->p_type != PT_LOAD) {
516 continue;
517 }
518 found_pt_load = true;
519
520 if (phdr->p_vaddr < min_vaddr) {
521 min_vaddr = phdr->p_vaddr;
522 }
523
524 if (phdr->p_vaddr + phdr->p_memsz > max_vaddr) {
525 max_vaddr = phdr->p_vaddr + phdr->p_memsz;
526 }
527 }
528 if (!found_pt_load) {
529 min_vaddr = 0;
530 }
531
532 min_vaddr = PAGE_START(min_vaddr);
533 max_vaddr = PAGE_END(max_vaddr);
534
535 if (out_min_vaddr != nullptr) {
536 *out_min_vaddr = min_vaddr;
537 }
538 if (out_max_vaddr != nullptr) {
539 *out_max_vaddr = max_vaddr;
540 }
541 return max_vaddr - min_vaddr;
542 }
543
544 // Returns the maximum p_align associated with a loadable segment in the ELF
545 // program header table. Used to determine whether the file should be loaded at
546 // a specific virtual address alignment for use with huge pages.
phdr_table_get_maximum_alignment(const ElfW (Phdr)* phdr_table,size_t phdr_count)547 size_t phdr_table_get_maximum_alignment(const ElfW(Phdr)* phdr_table, size_t phdr_count) {
548 size_t maximum_alignment = PAGE_SIZE;
549
550 for (size_t i = 0; i < phdr_count; ++i) {
551 const ElfW(Phdr)* phdr = &phdr_table[i];
552
553 // p_align must be 0, 1, or a positive, integral power of two.
554 if (phdr->p_type != PT_LOAD || ((phdr->p_align & (phdr->p_align - 1)) != 0)) {
555 continue;
556 }
557
558 if (phdr->p_align > maximum_alignment) {
559 maximum_alignment = phdr->p_align;
560 }
561 }
562
563 #if defined(__LP64__)
564 return maximum_alignment;
565 #else
566 return PAGE_SIZE;
567 #endif
568 }
569
570 // Reserve a virtual address range such that if it's limits were extended to the next 2**align
571 // boundary, it would not overlap with any existing mappings.
ReserveWithAlignmentPadding(size_t size,size_t mapping_align,size_t start_align,void ** out_gap_start,size_t * out_gap_size)572 static void* ReserveWithAlignmentPadding(size_t size, size_t mapping_align, size_t start_align,
573 void** out_gap_start, size_t* out_gap_size) {
574 int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
575 // Reserve enough space to properly align the library's start address.
576 mapping_align = std::max(mapping_align, start_align);
577 if (mapping_align == PAGE_SIZE) {
578 void* mmap_ptr = mmap(nullptr, size, PROT_NONE, mmap_flags, -1, 0);
579 if (mmap_ptr == MAP_FAILED) {
580 return nullptr;
581 }
582 return mmap_ptr;
583 }
584
585 // Minimum alignment of shared library gap. For efficiency, this should match the second level
586 // page size of the platform.
587 #if defined(__LP64__)
588 constexpr size_t kGapAlignment = 1ul << 21; // 2MB
589 #else
590 constexpr size_t kGapAlignment = 0;
591 #endif
592 // Maximum gap size, in the units of kGapAlignment.
593 constexpr size_t kMaxGapUnits = 32;
594 // Allocate enough space so that the end of the desired region aligned up is still inside the
595 // mapping.
596 size_t mmap_size = align_up(size, mapping_align) + mapping_align - PAGE_SIZE;
597 uint8_t* mmap_ptr =
598 reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
599 if (mmap_ptr == MAP_FAILED) {
600 return nullptr;
601 }
602 size_t gap_size = 0;
603 size_t first_byte = reinterpret_cast<size_t>(align_up(mmap_ptr, mapping_align));
604 size_t last_byte = reinterpret_cast<size_t>(align_down(mmap_ptr + mmap_size, mapping_align) - 1);
605 if (kGapAlignment && first_byte / kGapAlignment != last_byte / kGapAlignment) {
606 // This library crosses a 2MB boundary and will fragment a new huge page.
607 // Lets take advantage of that and insert a random number of inaccessible huge pages before that
608 // to improve address randomization and make it harder to locate this library code by probing.
609 munmap(mmap_ptr, mmap_size);
610 mapping_align = std::max(mapping_align, kGapAlignment);
611 gap_size =
612 kGapAlignment * (is_first_stage_init() ? 1 : arc4random_uniform(kMaxGapUnits - 1) + 1);
613 mmap_size = align_up(size + gap_size, mapping_align) + mapping_align - PAGE_SIZE;
614 mmap_ptr = reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
615 if (mmap_ptr == MAP_FAILED) {
616 return nullptr;
617 }
618 }
619
620 uint8_t *gap_end, *gap_start;
621 if (gap_size) {
622 gap_end = align_down(mmap_ptr + mmap_size, kGapAlignment);
623 gap_start = gap_end - gap_size;
624 } else {
625 gap_start = gap_end = mmap_ptr + mmap_size;
626 }
627
628 uint8_t* first = align_up(mmap_ptr, mapping_align);
629 uint8_t* last = align_down(gap_start, mapping_align) - size;
630
631 // arc4random* is not available in first stage init because /dev/urandom hasn't yet been
632 // created. Don't randomize then.
633 size_t n = is_first_stage_init() ? 0 : arc4random_uniform((last - first) / start_align + 1);
634 uint8_t* start = first + n * start_align;
635 // Unmap the extra space around the allocation.
636 // Keep it mapped PROT_NONE on 64-bit targets where address space is plentiful to make it harder
637 // to defeat ASLR by probing for readable memory mappings.
638 munmap(mmap_ptr, start - mmap_ptr);
639 munmap(start + size, gap_start - (start + size));
640 if (gap_end != mmap_ptr + mmap_size) {
641 munmap(gap_end, mmap_ptr + mmap_size - gap_end);
642 }
643 *out_gap_start = gap_start;
644 *out_gap_size = gap_size;
645 return start;
646 }
647
648 // Reserve a virtual address range big enough to hold all loadable
649 // segments of a program header table. This is done by creating a
650 // private anonymous mmap() with PROT_NONE.
ReserveAddressSpace(address_space_params * address_space)651 bool ElfReader::ReserveAddressSpace(address_space_params* address_space) {
652 ElfW(Addr) min_vaddr;
653 load_size_ = phdr_table_get_load_size(phdr_table_, phdr_num_, &min_vaddr);
654 if (load_size_ == 0) {
655 DL_ERR("\"%s\" has no loadable segments", name_.c_str());
656 return false;
657 }
658
659 uint8_t* addr = reinterpret_cast<uint8_t*>(min_vaddr);
660 void* start;
661
662 if (load_size_ > address_space->reserved_size) {
663 if (address_space->must_use_address) {
664 DL_ERR("reserved address space %zd smaller than %zd bytes needed for \"%s\"",
665 load_size_ - address_space->reserved_size, load_size_, name_.c_str());
666 return false;
667 }
668 size_t start_alignment = PAGE_SIZE;
669 if (get_transparent_hugepages_supported() && get_application_target_sdk_version() >= 31) {
670 size_t maximum_alignment = phdr_table_get_maximum_alignment(phdr_table_, phdr_num_);
671 // Limit alignment to PMD size as other alignments reduce the number of
672 // bits available for ASLR for no benefit.
673 start_alignment = maximum_alignment == kPmdSize ? kPmdSize : PAGE_SIZE;
674 }
675 start = ReserveWithAlignmentPadding(load_size_, kLibraryAlignment, start_alignment, &gap_start_,
676 &gap_size_);
677 if (start == nullptr) {
678 DL_ERR("couldn't reserve %zd bytes of address space for \"%s\"", load_size_, name_.c_str());
679 return false;
680 }
681 } else {
682 start = address_space->start_addr;
683 gap_start_ = nullptr;
684 gap_size_ = 0;
685 mapped_by_caller_ = true;
686
687 // Update the reserved address space to subtract the space used by this library.
688 address_space->start_addr = reinterpret_cast<uint8_t*>(address_space->start_addr) + load_size_;
689 address_space->reserved_size -= load_size_;
690 }
691
692 load_start_ = start;
693 load_bias_ = reinterpret_cast<uint8_t*>(start) - addr;
694 return true;
695 }
696
LoadSegments()697 bool ElfReader::LoadSegments() {
698 for (size_t i = 0; i < phdr_num_; ++i) {
699 const ElfW(Phdr)* phdr = &phdr_table_[i];
700
701 if (phdr->p_type != PT_LOAD) {
702 continue;
703 }
704
705 // Segment addresses in memory.
706 ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
707 ElfW(Addr) seg_end = seg_start + phdr->p_memsz;
708
709 ElfW(Addr) seg_page_start = PAGE_START(seg_start);
710 ElfW(Addr) seg_page_end = PAGE_END(seg_end);
711
712 ElfW(Addr) seg_file_end = seg_start + phdr->p_filesz;
713
714 // File offsets.
715 ElfW(Addr) file_start = phdr->p_offset;
716 ElfW(Addr) file_end = file_start + phdr->p_filesz;
717
718 ElfW(Addr) file_page_start = PAGE_START(file_start);
719 ElfW(Addr) file_length = file_end - file_page_start;
720
721 if (file_size_ <= 0) {
722 DL_ERR("\"%s\" invalid file size: %" PRId64, name_.c_str(), file_size_);
723 return false;
724 }
725
726 if (file_end > static_cast<size_t>(file_size_)) {
727 DL_ERR("invalid ELF file \"%s\" load segment[%zd]:"
728 " p_offset (%p) + p_filesz (%p) ( = %p) past end of file (0x%" PRIx64 ")",
729 name_.c_str(), i, reinterpret_cast<void*>(phdr->p_offset),
730 reinterpret_cast<void*>(phdr->p_filesz),
731 reinterpret_cast<void*>(file_end), file_size_);
732 return false;
733 }
734
735 if (file_length != 0) {
736 int prot = PFLAGS_TO_PROT(phdr->p_flags);
737 if ((prot & (PROT_EXEC | PROT_WRITE)) == (PROT_EXEC | PROT_WRITE)) {
738 // W + E PT_LOAD segments are not allowed in O.
739 if (get_application_target_sdk_version() >= 26) {
740 DL_ERR_AND_LOG("\"%s\": W+E load segments are not allowed", name_.c_str());
741 return false;
742 }
743 DL_WARN_documented_change(26,
744 "writable-and-executable-segments-enforced-for-api-level-26",
745 "\"%s\" has load segments that are both writable and executable",
746 name_.c_str());
747 add_dlwarning(name_.c_str(), "W+E load segments");
748 }
749
750 void* seg_addr = mmap64(reinterpret_cast<void*>(seg_page_start),
751 file_length,
752 prot,
753 MAP_FIXED|MAP_PRIVATE,
754 fd_,
755 file_offset_ + file_page_start);
756 if (seg_addr == MAP_FAILED) {
757 DL_ERR("couldn't map \"%s\" segment %zd: %s", name_.c_str(), i, strerror(errno));
758 return false;
759 }
760
761 // Mark segments as huge page eligible if they meet the requirements
762 // (executable and PMD aligned).
763 if ((phdr->p_flags & PF_X) && phdr->p_align == kPmdSize &&
764 get_transparent_hugepages_supported()) {
765 madvise(seg_addr, file_length, MADV_HUGEPAGE);
766 }
767 }
768
769 // if the segment is writable, and does not end on a page boundary,
770 // zero-fill it until the page limit.
771 if ((phdr->p_flags & PF_W) != 0 && PAGE_OFFSET(seg_file_end) > 0) {
772 memset(reinterpret_cast<void*>(seg_file_end), 0, PAGE_SIZE - PAGE_OFFSET(seg_file_end));
773 }
774
775 seg_file_end = PAGE_END(seg_file_end);
776
777 // seg_file_end is now the first page address after the file
778 // content. If seg_end is larger, we need to zero anything
779 // between them. This is done by using a private anonymous
780 // map for all extra pages.
781 if (seg_page_end > seg_file_end) {
782 size_t zeromap_size = seg_page_end - seg_file_end;
783 void* zeromap = mmap(reinterpret_cast<void*>(seg_file_end),
784 zeromap_size,
785 PFLAGS_TO_PROT(phdr->p_flags),
786 MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE,
787 -1,
788 0);
789 if (zeromap == MAP_FAILED) {
790 DL_ERR("couldn't zero fill \"%s\" gap: %s", name_.c_str(), strerror(errno));
791 return false;
792 }
793
794 prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, zeromap, zeromap_size, ".bss");
795 }
796 }
797 return true;
798 }
799
800 /* Used internally. Used to set the protection bits of all loaded segments
801 * with optional extra flags (i.e. really PROT_WRITE). Used by
802 * phdr_table_protect_segments and phdr_table_unprotect_segments.
803 */
_phdr_table_set_load_prot(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,int extra_prot_flags)804 static int _phdr_table_set_load_prot(const ElfW(Phdr)* phdr_table, size_t phdr_count,
805 ElfW(Addr) load_bias, int extra_prot_flags) {
806 const ElfW(Phdr)* phdr = phdr_table;
807 const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
808
809 for (; phdr < phdr_limit; phdr++) {
810 if (phdr->p_type != PT_LOAD || (phdr->p_flags & PF_W) != 0) {
811 continue;
812 }
813
814 ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
815 ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
816
817 int prot = PFLAGS_TO_PROT(phdr->p_flags) | extra_prot_flags;
818 if ((prot & PROT_WRITE) != 0) {
819 // make sure we're never simultaneously writable / executable
820 prot &= ~PROT_EXEC;
821 }
822 #if defined(__aarch64__)
823 if ((prot & PROT_EXEC) == 0) {
824 // Though it is not specified don't add PROT_BTI if segment is not
825 // executable.
826 prot &= ~PROT_BTI;
827 }
828 #endif
829
830 int ret =
831 mprotect(reinterpret_cast<void*>(seg_page_start), seg_page_end - seg_page_start, prot);
832 if (ret < 0) {
833 return -1;
834 }
835 }
836 return 0;
837 }
838
839 /* Restore the original protection modes for all loadable segments.
840 * You should only call this after phdr_table_unprotect_segments and
841 * applying all relocations.
842 *
843 * AArch64: also called from linker_main and ElfReader::Load to apply
844 * PROT_BTI for loaded main so and other so-s.
845 *
846 * Input:
847 * phdr_table -> program header table
848 * phdr_count -> number of entries in tables
849 * load_bias -> load bias
850 * prop -> GnuPropertySection or nullptr
851 * Return:
852 * 0 on error, -1 on failure (error code in errno).
853 */
phdr_table_protect_segments(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,const GnuPropertySection * prop __unused)854 int phdr_table_protect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count,
855 ElfW(Addr) load_bias, const GnuPropertySection* prop __unused) {
856 int prot = 0;
857 #if defined(__aarch64__)
858 if ((prop != nullptr) && prop->IsBTICompatible()) {
859 prot |= PROT_BTI;
860 }
861 #endif
862 return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, prot);
863 }
864
865 /* Change the protection of all loaded segments in memory to writable.
866 * This is useful before performing relocations. Once completed, you
867 * will have to call phdr_table_protect_segments to restore the original
868 * protection flags on all segments.
869 *
870 * Note that some writable segments can also have their content turned
871 * to read-only by calling phdr_table_protect_gnu_relro. This is no
872 * performed here.
873 *
874 * Input:
875 * phdr_table -> program header table
876 * phdr_count -> number of entries in tables
877 * load_bias -> load bias
878 * Return:
879 * 0 on error, -1 on failure (error code in errno).
880 */
phdr_table_unprotect_segments(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias)881 int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table,
882 size_t phdr_count, ElfW(Addr) load_bias) {
883 return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, PROT_WRITE);
884 }
885
886 /* Used internally by phdr_table_protect_gnu_relro and
887 * phdr_table_unprotect_gnu_relro.
888 */
_phdr_table_set_gnu_relro_prot(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,int prot_flags)889 static int _phdr_table_set_gnu_relro_prot(const ElfW(Phdr)* phdr_table, size_t phdr_count,
890 ElfW(Addr) load_bias, int prot_flags) {
891 const ElfW(Phdr)* phdr = phdr_table;
892 const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
893
894 for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
895 if (phdr->p_type != PT_GNU_RELRO) {
896 continue;
897 }
898
899 // Tricky: what happens when the relro segment does not start
900 // or end at page boundaries? We're going to be over-protective
901 // here and put every page touched by the segment as read-only.
902
903 // This seems to match Ian Lance Taylor's description of the
904 // feature at http://www.airs.com/blog/archives/189.
905
906 // Extract:
907 // Note that the current dynamic linker code will only work
908 // correctly if the PT_GNU_RELRO segment starts on a page
909 // boundary. This is because the dynamic linker rounds the
910 // p_vaddr field down to the previous page boundary. If
911 // there is anything on the page which should not be read-only,
912 // the program is likely to fail at runtime. So in effect the
913 // linker must only emit a PT_GNU_RELRO segment if it ensures
914 // that it starts on a page boundary.
915 ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
916 ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
917
918 int ret = mprotect(reinterpret_cast<void*>(seg_page_start),
919 seg_page_end - seg_page_start,
920 prot_flags);
921 if (ret < 0) {
922 return -1;
923 }
924 }
925 return 0;
926 }
927
928 /* Apply GNU relro protection if specified by the program header. This will
929 * turn some of the pages of a writable PT_LOAD segment to read-only, as
930 * specified by one or more PT_GNU_RELRO segments. This must be always
931 * performed after relocations.
932 *
933 * The areas typically covered are .got and .data.rel.ro, these are
934 * read-only from the program's POV, but contain absolute addresses
935 * that need to be relocated before use.
936 *
937 * Input:
938 * phdr_table -> program header table
939 * phdr_count -> number of entries in tables
940 * load_bias -> load bias
941 * Return:
942 * 0 on error, -1 on failure (error code in errno).
943 */
phdr_table_protect_gnu_relro(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias)944 int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table,
945 size_t phdr_count, ElfW(Addr) load_bias) {
946 return _phdr_table_set_gnu_relro_prot(phdr_table, phdr_count, load_bias, PROT_READ);
947 }
948
949 /* Serialize the GNU relro segments to the given file descriptor. This can be
950 * performed after relocations to allow another process to later share the
951 * relocated segment, if it was loaded at the same address.
952 *
953 * Input:
954 * phdr_table -> program header table
955 * phdr_count -> number of entries in tables
956 * load_bias -> load bias
957 * fd -> writable file descriptor to use
958 * file_offset -> pointer to offset into file descriptor to use/update
959 * Return:
960 * 0 on error, -1 on failure (error code in errno).
961 */
phdr_table_serialize_gnu_relro(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,int fd,size_t * file_offset)962 int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table,
963 size_t phdr_count,
964 ElfW(Addr) load_bias,
965 int fd,
966 size_t* file_offset) {
967 const ElfW(Phdr)* phdr = phdr_table;
968 const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
969
970 for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
971 if (phdr->p_type != PT_GNU_RELRO) {
972 continue;
973 }
974
975 ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
976 ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
977 ssize_t size = seg_page_end - seg_page_start;
978
979 ssize_t written = TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<void*>(seg_page_start), size));
980 if (written != size) {
981 return -1;
982 }
983 void* map = mmap(reinterpret_cast<void*>(seg_page_start), size, PROT_READ,
984 MAP_PRIVATE|MAP_FIXED, fd, *file_offset);
985 if (map == MAP_FAILED) {
986 return -1;
987 }
988 *file_offset += size;
989 }
990 return 0;
991 }
992
993 /* Where possible, replace the GNU relro segments with mappings of the given
994 * file descriptor. This can be performed after relocations to allow a file
995 * previously created by phdr_table_serialize_gnu_relro in another process to
996 * replace the dirty relocated pages, saving memory, if it was loaded at the
997 * same address. We have to compare the data before we map over it, since some
998 * parts of the relro segment may not be identical due to other libraries in
999 * the process being loaded at different addresses.
1000 *
1001 * Input:
1002 * phdr_table -> program header table
1003 * phdr_count -> number of entries in tables
1004 * load_bias -> load bias
1005 * fd -> readable file descriptor to use
1006 * file_offset -> pointer to offset into file descriptor to use/update
1007 * Return:
1008 * 0 on error, -1 on failure (error code in errno).
1009 */
phdr_table_map_gnu_relro(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,int fd,size_t * file_offset)1010 int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table,
1011 size_t phdr_count,
1012 ElfW(Addr) load_bias,
1013 int fd,
1014 size_t* file_offset) {
1015 // Map the file at a temporary location so we can compare its contents.
1016 struct stat file_stat;
1017 if (TEMP_FAILURE_RETRY(fstat(fd, &file_stat)) != 0) {
1018 return -1;
1019 }
1020 off_t file_size = file_stat.st_size;
1021 void* temp_mapping = nullptr;
1022 if (file_size > 0) {
1023 temp_mapping = mmap(nullptr, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
1024 if (temp_mapping == MAP_FAILED) {
1025 return -1;
1026 }
1027 }
1028
1029 // Iterate over the relro segments and compare/remap the pages.
1030 const ElfW(Phdr)* phdr = phdr_table;
1031 const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
1032
1033 for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
1034 if (phdr->p_type != PT_GNU_RELRO) {
1035 continue;
1036 }
1037
1038 ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
1039 ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
1040
1041 char* file_base = static_cast<char*>(temp_mapping) + *file_offset;
1042 char* mem_base = reinterpret_cast<char*>(seg_page_start);
1043 size_t match_offset = 0;
1044 size_t size = seg_page_end - seg_page_start;
1045
1046 if (file_size - *file_offset < size) {
1047 // File is too short to compare to this segment. The contents are likely
1048 // different as well (it's probably for a different library version) so
1049 // just don't bother checking.
1050 break;
1051 }
1052
1053 while (match_offset < size) {
1054 // Skip over dissimilar pages.
1055 while (match_offset < size &&
1056 memcmp(mem_base + match_offset, file_base + match_offset, PAGE_SIZE) != 0) {
1057 match_offset += PAGE_SIZE;
1058 }
1059
1060 // Count similar pages.
1061 size_t mismatch_offset = match_offset;
1062 while (mismatch_offset < size &&
1063 memcmp(mem_base + mismatch_offset, file_base + mismatch_offset, PAGE_SIZE) == 0) {
1064 mismatch_offset += PAGE_SIZE;
1065 }
1066
1067 // Map over similar pages.
1068 if (mismatch_offset > match_offset) {
1069 void* map = mmap(mem_base + match_offset, mismatch_offset - match_offset,
1070 PROT_READ, MAP_PRIVATE|MAP_FIXED, fd, *file_offset + match_offset);
1071 if (map == MAP_FAILED) {
1072 munmap(temp_mapping, file_size);
1073 return -1;
1074 }
1075 }
1076
1077 match_offset = mismatch_offset;
1078 }
1079
1080 // Add to the base file offset in case there are multiple relro segments.
1081 *file_offset += size;
1082 }
1083 munmap(temp_mapping, file_size);
1084 return 0;
1085 }
1086
1087
1088 #if defined(__arm__)
1089
1090 # ifndef PT_ARM_EXIDX
1091 # define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */
1092 # endif
1093
1094 /* Return the address and size of the .ARM.exidx section in memory,
1095 * if present.
1096 *
1097 * Input:
1098 * phdr_table -> program header table
1099 * phdr_count -> number of entries in tables
1100 * load_bias -> load bias
1101 * Output:
1102 * arm_exidx -> address of table in memory (null on failure).
1103 * arm_exidx_count -> number of items in table (0 on failure).
1104 * Return:
1105 * 0 on error, -1 on failure (_no_ error code in errno)
1106 */
phdr_table_get_arm_exidx(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,ElfW (Addr)** arm_exidx,size_t * arm_exidx_count)1107 int phdr_table_get_arm_exidx(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1108 ElfW(Addr) load_bias,
1109 ElfW(Addr)** arm_exidx, size_t* arm_exidx_count) {
1110 const ElfW(Phdr)* phdr = phdr_table;
1111 const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
1112
1113 for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
1114 if (phdr->p_type != PT_ARM_EXIDX) {
1115 continue;
1116 }
1117
1118 *arm_exidx = reinterpret_cast<ElfW(Addr)*>(load_bias + phdr->p_vaddr);
1119 *arm_exidx_count = phdr->p_memsz / 8;
1120 return 0;
1121 }
1122 *arm_exidx = nullptr;
1123 *arm_exidx_count = 0;
1124 return -1;
1125 }
1126 #endif
1127
1128 /* Return the address and size of the ELF file's .dynamic section in memory,
1129 * or null if missing.
1130 *
1131 * Input:
1132 * phdr_table -> program header table
1133 * phdr_count -> number of entries in tables
1134 * load_bias -> load bias
1135 * Output:
1136 * dynamic -> address of table in memory (null on failure).
1137 * dynamic_flags -> protection flags for section (unset on failure)
1138 * Return:
1139 * void
1140 */
phdr_table_get_dynamic_section(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,ElfW (Dyn)** dynamic,ElfW (Word)* dynamic_flags)1141 void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1142 ElfW(Addr) load_bias, ElfW(Dyn)** dynamic,
1143 ElfW(Word)* dynamic_flags) {
1144 *dynamic = nullptr;
1145 for (size_t i = 0; i<phdr_count; ++i) {
1146 const ElfW(Phdr)& phdr = phdr_table[i];
1147 if (phdr.p_type == PT_DYNAMIC) {
1148 *dynamic = reinterpret_cast<ElfW(Dyn)*>(load_bias + phdr.p_vaddr);
1149 if (dynamic_flags) {
1150 *dynamic_flags = phdr.p_flags;
1151 }
1152 return;
1153 }
1154 }
1155 }
1156
1157 /* Return the program interpreter string, or nullptr if missing.
1158 *
1159 * Input:
1160 * phdr_table -> program header table
1161 * phdr_count -> number of entries in tables
1162 * load_bias -> load bias
1163 * Return:
1164 * pointer to the program interpreter string.
1165 */
phdr_table_get_interpreter_name(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias)1166 const char* phdr_table_get_interpreter_name(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1167 ElfW(Addr) load_bias) {
1168 for (size_t i = 0; i<phdr_count; ++i) {
1169 const ElfW(Phdr)& phdr = phdr_table[i];
1170 if (phdr.p_type == PT_INTERP) {
1171 return reinterpret_cast<const char*>(load_bias + phdr.p_vaddr);
1172 }
1173 }
1174 return nullptr;
1175 }
1176
1177 // Sets loaded_phdr_ to the address of the program header table as it appears
1178 // in the loaded segments in memory. This is in contrast with phdr_table_,
1179 // which is temporary and will be released before the library is relocated.
FindPhdr()1180 bool ElfReader::FindPhdr() {
1181 const ElfW(Phdr)* phdr_limit = phdr_table_ + phdr_num_;
1182
1183 // If there is a PT_PHDR, use it directly.
1184 for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
1185 if (phdr->p_type == PT_PHDR) {
1186 return CheckPhdr(load_bias_ + phdr->p_vaddr);
1187 }
1188 }
1189
1190 // Otherwise, check the first loadable segment. If its file offset
1191 // is 0, it starts with the ELF header, and we can trivially find the
1192 // loaded program header from it.
1193 for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
1194 if (phdr->p_type == PT_LOAD) {
1195 if (phdr->p_offset == 0) {
1196 ElfW(Addr) elf_addr = load_bias_ + phdr->p_vaddr;
1197 const ElfW(Ehdr)* ehdr = reinterpret_cast<const ElfW(Ehdr)*>(elf_addr);
1198 ElfW(Addr) offset = ehdr->e_phoff;
1199 return CheckPhdr(reinterpret_cast<ElfW(Addr)>(ehdr) + offset);
1200 }
1201 break;
1202 }
1203 }
1204
1205 DL_ERR("can't find loaded phdr for \"%s\"", name_.c_str());
1206 return false;
1207 }
1208
1209 // Tries to find .note.gnu.property section.
1210 // It is not considered an error if such section is missing.
FindGnuPropertySection()1211 bool ElfReader::FindGnuPropertySection() {
1212 #if defined(__aarch64__)
1213 note_gnu_property_ = GnuPropertySection(phdr_table_, phdr_num_, load_start(), name_.c_str());
1214 #endif
1215 return true;
1216 }
1217
1218 // Ensures that our program header is actually within a loadable
1219 // segment. This should help catch badly-formed ELF files that
1220 // would cause the linker to crash later when trying to access it.
CheckPhdr(ElfW (Addr)loaded)1221 bool ElfReader::CheckPhdr(ElfW(Addr) loaded) {
1222 const ElfW(Phdr)* phdr_limit = phdr_table_ + phdr_num_;
1223 ElfW(Addr) loaded_end = loaded + (phdr_num_ * sizeof(ElfW(Phdr)));
1224 for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
1225 if (phdr->p_type != PT_LOAD) {
1226 continue;
1227 }
1228 ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
1229 ElfW(Addr) seg_end = phdr->p_filesz + seg_start;
1230 if (seg_start <= loaded && loaded_end <= seg_end) {
1231 loaded_phdr_ = reinterpret_cast<const ElfW(Phdr)*>(loaded);
1232 return true;
1233 }
1234 }
1235 DL_ERR("\"%s\" loaded phdr %p not in loadable segment",
1236 name_.c_str(), reinterpret_cast<void*>(loaded));
1237 return false;
1238 }
1239