• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                                                &note_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