xref: /aosp_15_r20/bionic/linker/linker_phdr.cpp (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
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_debug.h"
41 #include "linker_dlwarning.h"
42 #include "linker_globals.h"
43 #include "linker_logger.h"
44 #include "linker_main.h"
45 #include "linker_soinfo.h"
46 #include "linker_utils.h"
47 
48 #include "private/bionic_asm_note.h"
49 #include "private/CFIShadow.h" // For kLibraryAlignment
50 #include "private/elf_note.h"
51 
52 #include <android-base/file.h>
53 #include <android-base/properties.h>
54 
GetTargetElfMachine()55 static int GetTargetElfMachine() {
56 #if defined(__arm__)
57   return EM_ARM;
58 #elif defined(__aarch64__)
59   return EM_AARCH64;
60 #elif defined(__i386__)
61   return EM_386;
62 #elif defined(__riscv)
63   return EM_RISCV;
64 #elif defined(__x86_64__)
65   return EM_X86_64;
66 #endif
67 }
68 
69 /**
70   TECHNICAL NOTE ON ELF LOADING.
71 
72   An ELF file's program header table contains one or more PT_LOAD
73   segments, which corresponds to portions of the file that need to
74   be mapped into the process' address space.
75 
76   Each loadable segment has the following important properties:
77 
78     p_offset  -> segment file offset
79     p_filesz  -> segment file size
80     p_memsz   -> segment memory size (always >= p_filesz)
81     p_vaddr   -> segment's virtual address
82     p_flags   -> segment flags (e.g. readable, writable, executable)
83     p_align   -> segment's in-memory and in-file alignment
84 
85   We will ignore the p_paddr field of ElfW(Phdr) for now.
86 
87   The loadable segments can be seen as a list of [p_vaddr ... p_vaddr+p_memsz)
88   ranges of virtual addresses. A few rules apply:
89 
90   - the virtual address ranges should not overlap.
91 
92   - if a segment's p_filesz is smaller than its p_memsz, the extra bytes
93     between them should always be initialized to 0.
94 
95   - ranges do not necessarily start or end at page boundaries. Two distinct
96     segments can have their start and end on the same page. In this case, the
97     page inherits the mapping flags of the latter segment.
98 
99   Finally, the real load addrs of each segment is not p_vaddr. Instead the
100   loader decides where to load the first segment, then will load all others
101   relative to the first one to respect the initial range layout.
102 
103   For example, consider the following list:
104 
105     [ offset:0,      filesz:0x4000, memsz:0x4000, vaddr:0x30000 ],
106     [ offset:0x4000, filesz:0x2000, memsz:0x8000, vaddr:0x40000 ],
107 
108   This corresponds to two segments that cover these virtual address ranges:
109 
110        0x30000...0x34000
111        0x40000...0x48000
112 
113   If the loader decides to load the first segment at address 0xa0000000
114   then the segments' load address ranges will be:
115 
116        0xa0030000...0xa0034000
117        0xa0040000...0xa0048000
118 
119   In other words, all segments must be loaded at an address that has the same
120   constant offset from their p_vaddr value. This offset is computed as the
121   difference between the first segment's load address, and its p_vaddr value.
122 
123   However, in practice, segments do _not_ start at page boundaries. Since we
124   can only memory-map at page boundaries, this means that the bias is
125   computed as:
126 
127        load_bias = phdr0_load_address - page_start(phdr0->p_vaddr)
128 
129   (NOTE: The value must be used as a 32-bit unsigned integer, to deal with
130           possible wrap around UINT32_MAX for possible large p_vaddr values).
131 
132   And that the phdr0_load_address must start at a page boundary, with
133   the segment's real content starting at:
134 
135        phdr0_load_address + page_offset(phdr0->p_vaddr)
136 
137   Note that ELF requires the following condition to make the mmap()-ing work:
138 
139       page_offset(phdr0->p_vaddr) == page_offset(phdr0->p_offset)
140 
141   The load_bias must be added to any p_vaddr value read from the ELF file to
142   determine the corresponding memory address.
143 
144  **/
145 
146 static const size_t kPageSize = page_size();
147 
148 /*
149  * Generic PMD size calculation:
150  *    - Each page table (PT) is of size 1 page.
151  *    - Each page table entry (PTE) is of size 64 bits.
152  *    - Each PTE locates one physical page frame (PFN) of size 1 page.
153  *    - A PMD entry locates 1 page table (PT)
154  *
155  *   PMD size = Num entries in a PT * page_size
156  */
157 static const size_t kPmdSize = (kPageSize / sizeof(uint64_t)) * kPageSize;
158 
ElfReader()159 ElfReader::ElfReader()
160     : did_read_(false), did_load_(false), fd_(-1), file_offset_(0), file_size_(0), phdr_num_(0),
161       phdr_table_(nullptr), shdr_table_(nullptr), shdr_num_(0), dynamic_(nullptr), strtab_(nullptr),
162       strtab_size_(0), load_start_(nullptr), load_size_(0), load_bias_(0), loaded_phdr_(nullptr),
163       mapped_by_caller_(false) {
164 }
165 
Read(const char * name,int fd,off64_t file_offset,off64_t file_size)166 bool ElfReader::Read(const char* name, int fd, off64_t file_offset, off64_t file_size) {
167   if (did_read_) {
168     return true;
169   }
170   name_ = name;
171   fd_ = fd;
172   file_offset_ = file_offset;
173   file_size_ = file_size;
174 
175   if (ReadElfHeader() &&
176       VerifyElfHeader() &&
177       ReadProgramHeaders() &&
178       ReadSectionHeaders() &&
179       ReadDynamicSection() &&
180       ReadPadSegmentNote()) {
181     did_read_ = true;
182   }
183 
184   if (kPageSize == 0x4000 && phdr_table_get_minimum_alignment(phdr_table_, phdr_num_) == 0x1000) {
185     // This prop needs to be read on 16KiB devices for each ELF where min_palign is 4KiB.
186     // It cannot be cached since the developer may toggle app compat on/off.
187     // This check will be removed once app compat is made the default on 16KiB devices.
188     should_use_16kib_app_compat_ =
189         ::android::base::GetBoolProperty("bionic.linker.16kb.app_compat.enabled", false) ||
190         get_16kb_appcompat_mode();
191   }
192 
193   return did_read_;
194 }
195 
Load(address_space_params * address_space)196 bool ElfReader::Load(address_space_params* address_space) {
197   CHECK(did_read_);
198   if (did_load_) {
199     return true;
200   }
201   bool reserveSuccess = ReserveAddressSpace(address_space);
202   if (reserveSuccess && LoadSegments() && FindPhdr() &&
203       FindGnuPropertySection()) {
204     did_load_ = true;
205 #if defined(__aarch64__)
206     // For Armv8.5-A loaded executable segments may require PROT_BTI.
207     if (note_gnu_property_.IsBTICompatible()) {
208       did_load_ =
209           (phdr_table_protect_segments(phdr_table_, phdr_num_, load_bias_, should_pad_segments_,
210                                        should_use_16kib_app_compat_, &note_gnu_property_) == 0);
211     }
212 #endif
213   }
214   if (reserveSuccess && !did_load_) {
215     if (load_start_ != nullptr && load_size_ != 0) {
216       if (!mapped_by_caller_) {
217         munmap(load_start_, load_size_);
218       }
219     }
220   }
221 
222   return did_load_;
223 }
224 
get_string(ElfW (Word)index) const225 const char* ElfReader::get_string(ElfW(Word) index) const {
226   CHECK(strtab_ != nullptr);
227   CHECK(index < strtab_size_);
228 
229   return strtab_ + index;
230 }
231 
ReadElfHeader()232 bool ElfReader::ReadElfHeader() {
233   ssize_t rc = TEMP_FAILURE_RETRY(pread64(fd_, &header_, sizeof(header_), file_offset_));
234   if (rc < 0) {
235     DL_ERR("can't read file \"%s\": %s", name_.c_str(), strerror(errno));
236     return false;
237   }
238 
239   if (rc != sizeof(header_)) {
240     DL_ERR("\"%s\" is too small to be an ELF executable: only found %zd bytes", name_.c_str(),
241            static_cast<size_t>(rc));
242     return false;
243   }
244   return true;
245 }
246 
EM_to_string(int em)247 static const char* EM_to_string(int em) {
248   if (em == EM_386) return "EM_386";
249   if (em == EM_AARCH64) return "EM_AARCH64";
250   if (em == EM_ARM) return "EM_ARM";
251   if (em == EM_RISCV) return "EM_RISCV";
252   if (em == EM_X86_64) return "EM_X86_64";
253   return "EM_???";
254 }
255 
VerifyElfHeader()256 bool ElfReader::VerifyElfHeader() {
257   if (memcmp(header_.e_ident, ELFMAG, SELFMAG) != 0) {
258     DL_ERR("\"%s\" has bad ELF magic: %02x%02x%02x%02x", name_.c_str(),
259            header_.e_ident[0], header_.e_ident[1], header_.e_ident[2], header_.e_ident[3]);
260     return false;
261   }
262 
263   // Try to give a clear diagnostic for ELF class mismatches, since they're
264   // an easy mistake to make during the 32-bit/64-bit transition period.
265   int elf_class = header_.e_ident[EI_CLASS];
266 #if defined(__LP64__)
267   if (elf_class != ELFCLASS64) {
268     if (elf_class == ELFCLASS32) {
269       DL_ERR("\"%s\" is 32-bit instead of 64-bit", name_.c_str());
270     } else {
271       DL_ERR("\"%s\" has unknown ELF class: %d", name_.c_str(), elf_class);
272     }
273     return false;
274   }
275 #else
276   if (elf_class != ELFCLASS32) {
277     if (elf_class == ELFCLASS64) {
278       DL_ERR("\"%s\" is 64-bit instead of 32-bit", name_.c_str());
279     } else {
280       DL_ERR("\"%s\" has unknown ELF class: %d", name_.c_str(), elf_class);
281     }
282     return false;
283   }
284 #endif
285 
286   if (header_.e_ident[EI_DATA] != ELFDATA2LSB) {
287     DL_ERR("\"%s\" not little-endian: %d", name_.c_str(), header_.e_ident[EI_DATA]);
288     return false;
289   }
290 
291   if (header_.e_type != ET_DYN) {
292     DL_ERR("\"%s\" has unexpected e_type: %d", name_.c_str(), header_.e_type);
293     return false;
294   }
295 
296   if (header_.e_version != EV_CURRENT) {
297     DL_ERR("\"%s\" has unexpected e_version: %d", name_.c_str(), header_.e_version);
298     return false;
299   }
300 
301   if (header_.e_machine != GetTargetElfMachine()) {
302     DL_ERR("\"%s\" is for %s (%d) instead of %s (%d)",
303            name_.c_str(),
304            EM_to_string(header_.e_machine), header_.e_machine,
305            EM_to_string(GetTargetElfMachine()), GetTargetElfMachine());
306     return false;
307   }
308 
309   if (header_.e_shentsize != sizeof(ElfW(Shdr))) {
310     if (get_application_target_sdk_version() >= 26) {
311       DL_ERR_AND_LOG("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)",
312                      name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
313       return false;
314     }
315     DL_WARN_documented_change(26,
316                               "invalid-elf-header_section-headers-enforced-for-api-level-26",
317                               "\"%s\" has unsupported e_shentsize 0x%x (expected 0x%zx)",
318                               name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
319     add_dlwarning(name_.c_str(), "has invalid ELF header");
320   }
321 
322   if (header_.e_shstrndx == 0) {
323     if (get_application_target_sdk_version() >= 26) {
324       DL_ERR_AND_LOG("\"%s\" has invalid e_shstrndx", name_.c_str());
325       return false;
326     }
327     DL_WARN_documented_change(26,
328                               "invalid-elf-header_section-headers-enforced-for-api-level-26",
329                               "\"%s\" has invalid e_shstrndx", name_.c_str());
330     add_dlwarning(name_.c_str(), "has invalid ELF header");
331   }
332 
333   return true;
334 }
335 
CheckFileRange(ElfW (Addr)offset,size_t size,size_t alignment)336 bool ElfReader::CheckFileRange(ElfW(Addr) offset, size_t size, size_t alignment) {
337   off64_t range_start;
338   off64_t range_end;
339 
340   // Only header can be located at the 0 offset... This function called to
341   // check DYNSYM and DYNAMIC sections and phdr/shdr - none of them can be
342   // at offset 0.
343 
344   return offset > 0 &&
345          safe_add(&range_start, file_offset_, offset) &&
346          safe_add(&range_end, range_start, size) &&
347          (range_start < file_size_) &&
348          (range_end <= file_size_) &&
349          ((offset % alignment) == 0);
350 }
351 
352 // Loads the program header table from an ELF file into a read-only private
353 // anonymous mmap-ed block.
ReadProgramHeaders()354 bool ElfReader::ReadProgramHeaders() {
355   phdr_num_ = header_.e_phnum;
356 
357   // Like the kernel, we only accept program header tables that
358   // are smaller than 64KiB.
359   if (phdr_num_ < 1 || phdr_num_ > 65536/sizeof(ElfW(Phdr))) {
360     DL_ERR("\"%s\" has invalid e_phnum: %zd", name_.c_str(), phdr_num_);
361     return false;
362   }
363 
364   // Boundary checks
365   size_t size = phdr_num_ * sizeof(ElfW(Phdr));
366   if (!CheckFileRange(header_.e_phoff, size, alignof(ElfW(Phdr)))) {
367     DL_ERR_AND_LOG("\"%s\" has invalid phdr offset/size: %zu/%zu",
368                    name_.c_str(),
369                    static_cast<size_t>(header_.e_phoff),
370                    size);
371     return false;
372   }
373 
374   if (!phdr_fragment_.Map(fd_, file_offset_, header_.e_phoff, size)) {
375     DL_ERR("\"%s\" phdr mmap failed: %m", name_.c_str());
376     return false;
377   }
378 
379   phdr_table_ = static_cast<ElfW(Phdr)*>(phdr_fragment_.data());
380   return true;
381 }
382 
ReadSectionHeaders()383 bool ElfReader::ReadSectionHeaders() {
384   shdr_num_ = header_.e_shnum;
385 
386   if (shdr_num_ == 0) {
387     DL_ERR_AND_LOG("\"%s\" has no section headers", name_.c_str());
388     return false;
389   }
390 
391   size_t size = shdr_num_ * sizeof(ElfW(Shdr));
392   if (!CheckFileRange(header_.e_shoff, size, alignof(const ElfW(Shdr)))) {
393     DL_ERR_AND_LOG("\"%s\" has invalid shdr offset/size: %zu/%zu",
394                    name_.c_str(),
395                    static_cast<size_t>(header_.e_shoff),
396                    size);
397     return false;
398   }
399 
400   if (!shdr_fragment_.Map(fd_, file_offset_, header_.e_shoff, size)) {
401     DL_ERR("\"%s\" shdr mmap failed: %m", name_.c_str());
402     return false;
403   }
404 
405   shdr_table_ = static_cast<const ElfW(Shdr)*>(shdr_fragment_.data());
406   return true;
407 }
408 
ReadDynamicSection()409 bool ElfReader::ReadDynamicSection() {
410   // 1. Find .dynamic section (in section headers)
411   const ElfW(Shdr)* dynamic_shdr = nullptr;
412   for (size_t i = 0; i < shdr_num_; ++i) {
413     if (shdr_table_[i].sh_type == SHT_DYNAMIC) {
414       dynamic_shdr = &shdr_table_ [i];
415       break;
416     }
417   }
418 
419   if (dynamic_shdr == nullptr) {
420     DL_ERR_AND_LOG("\"%s\" .dynamic section header was not found", name_.c_str());
421     return false;
422   }
423 
424   // Make sure dynamic_shdr offset and size matches PT_DYNAMIC phdr
425   size_t pt_dynamic_offset = 0;
426   size_t pt_dynamic_filesz = 0;
427   for (size_t i = 0; i < phdr_num_; ++i) {
428     const ElfW(Phdr)* phdr = &phdr_table_[i];
429     if (phdr->p_type == PT_DYNAMIC) {
430       pt_dynamic_offset = phdr->p_offset;
431       pt_dynamic_filesz = phdr->p_filesz;
432     }
433   }
434 
435   if (pt_dynamic_offset != dynamic_shdr->sh_offset) {
436     if (get_application_target_sdk_version() >= 26) {
437       DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid offset: 0x%zx, "
438                      "expected to match PT_DYNAMIC offset: 0x%zx",
439                      name_.c_str(),
440                      static_cast<size_t>(dynamic_shdr->sh_offset),
441                      pt_dynamic_offset);
442       return false;
443     }
444     DL_WARN_documented_change(26,
445                               "invalid-elf-header_section-headers-enforced-for-api-level-26",
446                               "\"%s\" .dynamic section has invalid offset: 0x%zx "
447                               "(expected to match PT_DYNAMIC offset 0x%zx)",
448                               name_.c_str(),
449                               static_cast<size_t>(dynamic_shdr->sh_offset),
450                               pt_dynamic_offset);
451     add_dlwarning(name_.c_str(), "invalid .dynamic section");
452   }
453 
454   if (pt_dynamic_filesz != dynamic_shdr->sh_size) {
455     if (get_application_target_sdk_version() >= 26) {
456       DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid size: 0x%zx, "
457                      "expected to match PT_DYNAMIC filesz: 0x%zx",
458                      name_.c_str(),
459                      static_cast<size_t>(dynamic_shdr->sh_size),
460                      pt_dynamic_filesz);
461       return false;
462     }
463     DL_WARN_documented_change(26,
464                               "invalid-elf-header_section-headers-enforced-for-api-level-26",
465                               "\"%s\" .dynamic section has invalid size: 0x%zx "
466                               "(expected to match PT_DYNAMIC filesz 0x%zx)",
467                               name_.c_str(),
468                               static_cast<size_t>(dynamic_shdr->sh_size),
469                               pt_dynamic_filesz);
470     add_dlwarning(name_.c_str(), "invalid .dynamic section");
471   }
472 
473   if (dynamic_shdr->sh_link >= shdr_num_) {
474     DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid sh_link: %d",
475                    name_.c_str(),
476                    dynamic_shdr->sh_link);
477     return false;
478   }
479 
480   const ElfW(Shdr)* strtab_shdr = &shdr_table_[dynamic_shdr->sh_link];
481 
482   if (strtab_shdr->sh_type != SHT_STRTAB) {
483     DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid link(%d) sh_type: %d (expected SHT_STRTAB)",
484                    name_.c_str(), dynamic_shdr->sh_link, strtab_shdr->sh_type);
485     return false;
486   }
487 
488   if (!CheckFileRange(dynamic_shdr->sh_offset, dynamic_shdr->sh_size, alignof(const ElfW(Dyn)))) {
489     DL_ERR_AND_LOG("\"%s\" has invalid offset/size of .dynamic section", name_.c_str());
490     return false;
491   }
492 
493   if (!dynamic_fragment_.Map(fd_, file_offset_, dynamic_shdr->sh_offset, dynamic_shdr->sh_size)) {
494     DL_ERR("\"%s\" dynamic section mmap failed: %m", name_.c_str());
495     return false;
496   }
497 
498   dynamic_ = static_cast<const ElfW(Dyn)*>(dynamic_fragment_.data());
499 
500   if (!CheckFileRange(strtab_shdr->sh_offset, strtab_shdr->sh_size, alignof(const char))) {
501     DL_ERR_AND_LOG("\"%s\" has invalid offset/size of the .strtab section linked from .dynamic section",
502                    name_.c_str());
503     return false;
504   }
505 
506   if (!strtab_fragment_.Map(fd_, file_offset_, strtab_shdr->sh_offset, strtab_shdr->sh_size)) {
507     DL_ERR("\"%s\" strtab section mmap failed: %m", name_.c_str());
508     return false;
509   }
510 
511   strtab_ = static_cast<const char*>(strtab_fragment_.data());
512   strtab_size_ = strtab_fragment_.size();
513   return true;
514 }
515 
516 /* Returns the size of the extent of all the possibly non-contiguous
517  * loadable segments in an ELF program header table. This corresponds
518  * to the page-aligned size in bytes that needs to be reserved in the
519  * process' address space. If there are no loadable segments, 0 is
520  * returned.
521  *
522  * If out_min_vaddr or out_max_vaddr are not null, they will be
523  * set to the minimum and maximum addresses of pages to be reserved,
524  * or 0 if there is nothing to load.
525  */
phdr_table_get_load_size(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)* out_min_vaddr,ElfW (Addr)* out_max_vaddr)526 size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count,
527                                 ElfW(Addr)* out_min_vaddr,
528                                 ElfW(Addr)* out_max_vaddr) {
529   ElfW(Addr) min_vaddr = UINTPTR_MAX;
530   ElfW(Addr) max_vaddr = 0;
531 
532   bool found_pt_load = false;
533   for (size_t i = 0; i < phdr_count; ++i) {
534     const ElfW(Phdr)* phdr = &phdr_table[i];
535 
536     if (phdr->p_type != PT_LOAD) {
537       continue;
538     }
539     found_pt_load = true;
540 
541     if (phdr->p_vaddr < min_vaddr) {
542       min_vaddr = phdr->p_vaddr;
543     }
544 
545     if (phdr->p_vaddr + phdr->p_memsz > max_vaddr) {
546       max_vaddr = phdr->p_vaddr + phdr->p_memsz;
547     }
548   }
549   if (!found_pt_load) {
550     min_vaddr = 0;
551   }
552 
553   min_vaddr = page_start(min_vaddr);
554   max_vaddr = page_end(max_vaddr);
555 
556   if (out_min_vaddr != nullptr) {
557     *out_min_vaddr = min_vaddr;
558   }
559   if (out_max_vaddr != nullptr) {
560     *out_max_vaddr = max_vaddr;
561   }
562   return max_vaddr - min_vaddr;
563 }
564 
565 // Returns the maximum p_align associated with a loadable segment in the ELF
566 // program header table. Used to determine whether the file should be loaded at
567 // a specific virtual address alignment for use with huge pages.
phdr_table_get_maximum_alignment(const ElfW (Phdr)* phdr_table,size_t phdr_count)568 size_t phdr_table_get_maximum_alignment(const ElfW(Phdr)* phdr_table, size_t phdr_count) {
569   size_t maximum_alignment = page_size();
570 
571   for (size_t i = 0; i < phdr_count; ++i) {
572     const ElfW(Phdr)* phdr = &phdr_table[i];
573 
574     // p_align must be 0, 1, or a positive, integral power of two.
575     if (phdr->p_type != PT_LOAD || ((phdr->p_align & (phdr->p_align - 1)) != 0)) {
576       continue;
577     }
578 
579     maximum_alignment = std::max(maximum_alignment, static_cast<size_t>(phdr->p_align));
580   }
581 
582 #if defined(__LP64__)
583   return maximum_alignment;
584 #else
585   return page_size();
586 #endif
587 }
588 
589 // Returns the minimum p_align associated with a loadable segment in the ELF
590 // program header table. Used to determine if the program alignment is compatible
591 // with the page size of this system.
phdr_table_get_minimum_alignment(const ElfW (Phdr)* phdr_table,size_t phdr_count)592 size_t phdr_table_get_minimum_alignment(const ElfW(Phdr)* phdr_table, size_t phdr_count) {
593   size_t minimum_alignment = page_size();
594 
595   for (size_t i = 0; i < phdr_count; ++i) {
596     const ElfW(Phdr)* phdr = &phdr_table[i];
597 
598     // p_align must be 0, 1, or a positive, integral power of two.
599     if (phdr->p_type != PT_LOAD || ((phdr->p_align & (phdr->p_align - 1)) != 0)) {
600       continue;
601     }
602 
603     if (phdr->p_align <= 1) {
604       continue;
605     }
606 
607     minimum_alignment = std::min(minimum_alignment, static_cast<size_t>(phdr->p_align));
608   }
609 
610   return minimum_alignment;
611 }
612 
613 // Reserve a virtual address range such that if it's limits were extended to the next 2**align
614 // 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)615 static void* ReserveWithAlignmentPadding(size_t size, size_t mapping_align, size_t start_align,
616                                          void** out_gap_start, size_t* out_gap_size) {
617   int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
618   // Reserve enough space to properly align the library's start address.
619   mapping_align = std::max(mapping_align, start_align);
620   if (mapping_align == page_size()) {
621     void* mmap_ptr = mmap(nullptr, size, PROT_NONE, mmap_flags, -1, 0);
622     if (mmap_ptr == MAP_FAILED) {
623       return nullptr;
624     }
625     return mmap_ptr;
626   }
627 
628   // Minimum alignment of shared library gap. For efficiency, this should match the second level
629   // page size of the platform.
630 #if defined(__LP64__)
631   constexpr size_t kGapAlignment = 1ul << 21;  // 2MB
632 #else
633   constexpr size_t kGapAlignment = 0;
634 #endif
635   // Maximum gap size, in the units of kGapAlignment.
636   constexpr size_t kMaxGapUnits = 32;
637   // Allocate enough space so that the end of the desired region aligned up is still inside the
638   // mapping.
639   size_t mmap_size = align_up(size, mapping_align) + mapping_align - page_size();
640   uint8_t* mmap_ptr =
641       reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
642   if (mmap_ptr == MAP_FAILED) {
643     return nullptr;
644   }
645   size_t gap_size = 0;
646   size_t first_byte = reinterpret_cast<size_t>(align_up(mmap_ptr, mapping_align));
647   size_t last_byte = reinterpret_cast<size_t>(align_down(mmap_ptr + mmap_size, mapping_align) - 1);
648   if (kGapAlignment && first_byte / kGapAlignment != last_byte / kGapAlignment) {
649     // This library crosses a 2MB boundary and will fragment a new huge page.
650     // Lets take advantage of that and insert a random number of inaccessible huge pages before that
651     // to improve address randomization and make it harder to locate this library code by probing.
652     munmap(mmap_ptr, mmap_size);
653     mapping_align = std::max(mapping_align, kGapAlignment);
654     gap_size =
655         kGapAlignment * (is_first_stage_init() ? 1 : arc4random_uniform(kMaxGapUnits - 1) + 1);
656     mmap_size = align_up(size + gap_size, mapping_align) + mapping_align - page_size();
657     mmap_ptr = reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
658     if (mmap_ptr == MAP_FAILED) {
659       return nullptr;
660     }
661   }
662 
663   uint8_t *gap_end, *gap_start;
664   if (gap_size) {
665     gap_end = align_down(mmap_ptr + mmap_size, kGapAlignment);
666     gap_start = gap_end - gap_size;
667   } else {
668     gap_start = gap_end = mmap_ptr + mmap_size;
669   }
670 
671   uint8_t* first = align_up(mmap_ptr, mapping_align);
672   uint8_t* last = align_down(gap_start, mapping_align) - size;
673 
674   // arc4random* is not available in first stage init because /dev/urandom hasn't yet been
675   // created. Don't randomize then.
676   size_t n = is_first_stage_init() ? 0 : arc4random_uniform((last - first) / start_align + 1);
677   uint8_t* start = first + n * start_align;
678   // Unmap the extra space around the allocation.
679   // Keep it mapped PROT_NONE on 64-bit targets where address space is plentiful to make it harder
680   // to defeat ASLR by probing for readable memory mappings.
681   munmap(mmap_ptr, start - mmap_ptr);
682   munmap(start + size, gap_start - (start + size));
683   if (gap_end != mmap_ptr + mmap_size) {
684     munmap(gap_end, mmap_ptr + mmap_size - gap_end);
685   }
686   *out_gap_start = gap_start;
687   *out_gap_size = gap_size;
688   return start;
689 }
690 
691 // Reserve a virtual address range big enough to hold all loadable
692 // segments of a program header table. This is done by creating a
693 // private anonymous mmap() with PROT_NONE.
ReserveAddressSpace(address_space_params * address_space)694 bool ElfReader::ReserveAddressSpace(address_space_params* address_space) {
695   ElfW(Addr) min_vaddr;
696   load_size_ = phdr_table_get_load_size(phdr_table_, phdr_num_, &min_vaddr);
697   if (load_size_ == 0) {
698     DL_ERR("\"%s\" has no loadable segments", name_.c_str());
699     return false;
700   }
701 
702   if (should_use_16kib_app_compat_) {
703     // Reserve additional space for aligning the permission boundary in compat loading
704     // Up to kPageSize-kCompatPageSize additional space is needed, but reservation
705     // is done with mmap which gives kPageSize multiple-sized reservations.
706     load_size_ += kPageSize;
707   }
708 
709   uint8_t* addr = reinterpret_cast<uint8_t*>(min_vaddr);
710   void* start;
711 
712   if (load_size_ > address_space->reserved_size) {
713     if (address_space->must_use_address) {
714       DL_ERR("reserved address space %zd smaller than %zd bytes needed for \"%s\"",
715              load_size_ - address_space->reserved_size, load_size_, name_.c_str());
716       return false;
717     }
718     size_t start_alignment = page_size();
719     if (get_transparent_hugepages_supported() && get_application_target_sdk_version() >= 31) {
720       size_t maximum_alignment = phdr_table_get_maximum_alignment(phdr_table_, phdr_num_);
721       // Limit alignment to PMD size as other alignments reduce the number of
722       // bits available for ASLR for no benefit.
723       start_alignment = maximum_alignment == kPmdSize ? kPmdSize : page_size();
724     }
725     start = ReserveWithAlignmentPadding(load_size_, kLibraryAlignment, start_alignment, &gap_start_,
726                                         &gap_size_);
727     if (start == nullptr) {
728       DL_ERR("couldn't reserve %zd bytes of address space for \"%s\"", load_size_, name_.c_str());
729       return false;
730     }
731   } else {
732     start = address_space->start_addr;
733     gap_start_ = nullptr;
734     gap_size_ = 0;
735     mapped_by_caller_ = true;
736 
737     // Update the reserved address space to subtract the space used by this library.
738     address_space->start_addr = reinterpret_cast<uint8_t*>(address_space->start_addr) + load_size_;
739     address_space->reserved_size -= load_size_;
740   }
741 
742   load_start_ = start;
743   load_bias_ = reinterpret_cast<uint8_t*>(start) - addr;
744 
745   if (should_use_16kib_app_compat_) {
746     // In compat mode make the initial mapping RW since the ELF contents will be read
747     // into it; instead of mapped over it.
748     mprotect(reinterpret_cast<void*>(start), load_size_, PROT_READ | PROT_WRITE);
749   }
750 
751   return true;
752 }
753 
754 /*
755  * Returns true if the kernel supports page size migration for this process.
756  */
page_size_migration_supported()757 bool page_size_migration_supported() {
758 #if defined(__LP64__)
759   static bool pgsize_migration_enabled = []() {
760     std::string enabled;
761     if (!android::base::ReadFileToString("/sys/kernel/mm/pgsize_migration/enabled", &enabled)) {
762       return false;
763     }
764     return enabled.find("1") != std::string::npos;
765   }();
766   return pgsize_migration_enabled;
767 #else
768   return false;
769 #endif
770 }
771 
772 // Find the ELF note of type NT_ANDROID_TYPE_PAD_SEGMENT and check that the desc value is 1.
ReadPadSegmentNote()773 bool ElfReader::ReadPadSegmentNote() {
774   if (!page_size_migration_supported()) {
775     // Don't attempt to read the note, since segment extension isn't
776     // supported; but return true so that loading can continue normally.
777     return true;
778   }
779 
780   // The ELF can have multiple PT_NOTE's, check them all
781   for (size_t i = 0; i < phdr_num_; ++i) {
782     const ElfW(Phdr)* phdr = &phdr_table_[i];
783 
784     if (phdr->p_type != PT_NOTE) {
785       continue;
786     }
787 
788     // Some obfuscated ELFs may contain "empty" PT_NOTE program headers that don't
789     // point to any part of the ELF (p_memsz == 0). Skip these since there is
790     // nothing to decode. See: b/324468126
791     if (phdr->p_memsz == 0) {
792       continue;
793     }
794 
795     // If the PT_NOTE extends beyond the file. The ELF is doing something
796     // strange -- obfuscation, embedding hidden loaders, ...
797     //
798     // It doesn't contain the pad_segment note. Skip it to avoid SIGBUS
799     // by accesses beyond the file.
800     off64_t note_end_off = file_offset_ + phdr->p_offset + phdr->p_filesz;
801     if (note_end_off > file_size_) {
802       continue;
803     }
804 
805     // note_fragment is scoped to within the loop so that there is
806     // at most 1 PT_NOTE mapped at anytime during this search.
807     MappedFileFragment note_fragment;
808     if (!note_fragment.Map(fd_, file_offset_, phdr->p_offset, phdr->p_memsz)) {
809       DL_ERR("\"%s\": PT_NOTE mmap(nullptr, %p, PROT_READ, MAP_PRIVATE, %d, %p) failed: %m",
810              name_.c_str(), reinterpret_cast<void*>(phdr->p_memsz), fd_,
811              reinterpret_cast<void*>(page_start(file_offset_ + phdr->p_offset)));
812       return false;
813     }
814 
815     const ElfW(Nhdr)* note_hdr = nullptr;
816     const char* note_desc = nullptr;
817     if (!__get_elf_note(NT_ANDROID_TYPE_PAD_SEGMENT, "Android",
818                         reinterpret_cast<ElfW(Addr)>(note_fragment.data()),
819                         phdr, &note_hdr, &note_desc)) {
820       continue;
821     }
822 
823     if (note_hdr->n_descsz != sizeof(ElfW(Word))) {
824       DL_ERR("\"%s\" NT_ANDROID_TYPE_PAD_SEGMENT note has unexpected n_descsz: %u",
825              name_.c_str(), reinterpret_cast<unsigned int>(note_hdr->n_descsz));
826       return false;
827     }
828 
829     // 1 == enabled, 0 == disabled
830     should_pad_segments_ = *reinterpret_cast<const ElfW(Word)*>(note_desc) == 1;
831     return true;
832   }
833 
834   return true;
835 }
836 
_extend_load_segment_vma(const ElfW (Phdr)* phdr_table,size_t phdr_count,size_t phdr_idx,ElfW (Addr)* p_memsz,ElfW (Addr)* p_filesz,bool should_pad_segments,bool should_use_16kib_app_compat)837 static inline void _extend_load_segment_vma(const ElfW(Phdr)* phdr_table, size_t phdr_count,
838                                             size_t phdr_idx, ElfW(Addr)* p_memsz,
839                                             ElfW(Addr)* p_filesz, bool should_pad_segments,
840                                             bool should_use_16kib_app_compat) {
841   // NOTE: Segment extension is only applicable where the ELF's max-page-size > runtime page size;
842   // to save kernel VMA slab memory. 16KiB compat mode is the exact opposite scenario.
843   if (should_use_16kib_app_compat) {
844     return;
845   }
846 
847   const ElfW(Phdr)* phdr = &phdr_table[phdr_idx];
848   const ElfW(Phdr)* next = nullptr;
849   size_t next_idx = phdr_idx + 1;
850 
851   // Don't do segment extension for p_align > 64KiB, such ELFs already existed in the
852   // field e.g. 2MiB p_align for THPs and are relatively small in number.
853   //
854   // The kernel can only represent padding for p_align up to 64KiB. This is because
855   // the kernel uses 4 available bits in the vm_area_struct to represent padding
856   // extent; and so cannot enable mitigations to avoid breaking app compatibility for
857   // p_aligns > 64KiB.
858   //
859   // Don't perform segment extension on these to avoid app compatibility issues.
860   if (phdr->p_align <= kPageSize || phdr->p_align > 64*1024 || !should_pad_segments) {
861     return;
862   }
863 
864   if (next_idx < phdr_count && phdr_table[next_idx].p_type == PT_LOAD) {
865     next = &phdr_table[next_idx];
866   }
867 
868   // If this is the last LOAD segment, no extension is needed
869   if (!next || *p_memsz != *p_filesz) {
870     return;
871   }
872 
873   ElfW(Addr) next_start = page_start(next->p_vaddr);
874   ElfW(Addr) curr_end = page_end(phdr->p_vaddr + *p_memsz);
875 
876   // If adjacent segment mappings overlap, no extension is needed.
877   if (curr_end >= next_start) {
878     return;
879   }
880 
881   // Extend the LOAD segment mapping to be contiguous with that of
882   // the next LOAD segment.
883   ElfW(Addr) extend = next_start - curr_end;
884   *p_memsz += extend;
885   *p_filesz += extend;
886 }
887 
MapSegment(size_t seg_idx,size_t len)888 bool ElfReader::MapSegment(size_t seg_idx, size_t len) {
889   const ElfW(Phdr)* phdr = &phdr_table_[seg_idx];
890 
891   void* start = reinterpret_cast<void*>(page_start(phdr->p_vaddr + load_bias_));
892 
893   // The ELF could be being loaded directly from a zipped APK,
894   // the zip offset must be added to find the segment offset.
895   const ElfW(Addr) offset = file_offset_ + page_start(phdr->p_offset);
896 
897   int prot = PFLAGS_TO_PROT(phdr->p_flags);
898 
899   void* seg_addr = mmap64(start, len, prot, MAP_FIXED | MAP_PRIVATE, fd_, offset);
900 
901   if (seg_addr == MAP_FAILED) {
902     DL_ERR("couldn't map \"%s\" segment %zd: %m", name_.c_str(), seg_idx);
903     return false;
904   }
905 
906   // Mark segments as huge page eligible if they meet the requirements
907   if ((phdr->p_flags & PF_X) && phdr->p_align == kPmdSize &&
908       get_transparent_hugepages_supported()) {
909     madvise(seg_addr, len, MADV_HUGEPAGE);
910   }
911 
912   return true;
913 }
914 
ZeroFillSegment(const ElfW (Phdr)* phdr)915 void ElfReader::ZeroFillSegment(const ElfW(Phdr)* phdr) {
916   // NOTE: In 16KiB app compat mode, the ELF mapping is anonymous, meaning that
917   // RW segments are COW-ed from the kernel's zero page. So there is no need to
918   // explicitly zero-fill until the last page's limit.
919   if (should_use_16kib_app_compat_) {
920     return;
921   }
922 
923   ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
924   uint64_t unextended_seg_file_end = seg_start + phdr->p_filesz;
925 
926   // If the segment is writable, and does not end on a page boundary,
927   // zero-fill it until the page limit.
928   //
929   // Do not attempt to zero the extended region past the first partial page,
930   // since doing so may:
931   //   1) Result in a SIGBUS, as the region is not backed by the underlying
932   //      file.
933   //   2) Break the COW backing, faulting in new anon pages for a region
934   //      that will not be used.
935   if ((phdr->p_flags & PF_W) != 0 && page_offset(unextended_seg_file_end) > 0) {
936     memset(reinterpret_cast<void*>(unextended_seg_file_end), 0,
937            kPageSize - page_offset(unextended_seg_file_end));
938   }
939 }
940 
DropPaddingPages(const ElfW (Phdr)* phdr,uint64_t seg_file_end)941 void ElfReader::DropPaddingPages(const ElfW(Phdr)* phdr, uint64_t seg_file_end) {
942   // NOTE: Padding pages are only applicable where the ELF's max-page-size > runtime page size;
943   // 16KiB compat mode is the exact opposite scenario.
944   if (should_use_16kib_app_compat_) {
945     return;
946   }
947 
948   ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
949   uint64_t unextended_seg_file_end = seg_start + phdr->p_filesz;
950 
951   uint64_t pad_start = page_end(unextended_seg_file_end);
952   uint64_t pad_end = page_end(seg_file_end);
953   CHECK(pad_start <= pad_end);
954 
955   uint64_t pad_len = pad_end - pad_start;
956   if (pad_len == 0 || !page_size_migration_supported()) {
957     return;
958   }
959 
960   // Pages may be brought in due to readahead.
961   // Drop the padding (zero) pages, to avoid reclaim work later.
962   //
963   // NOTE: The madvise() here is special, as it also serves to hint to the
964   // kernel the portion of the LOAD segment that is padding.
965   //
966   // See: [1] https://android-review.googlesource.com/c/kernel/common/+/3032411
967   //      [2] https://android-review.googlesource.com/c/kernel/common/+/3048835
968   if (madvise(reinterpret_cast<void*>(pad_start), pad_len, MADV_DONTNEED)) {
969     DL_WARN("\"%s\": madvise(0x%" PRIx64 ", 0x%" PRIx64 ", MADV_DONTNEED) failed: %m",
970             name_.c_str(), pad_start, pad_len);
971   }
972 }
973 
MapBssSection(const ElfW (Phdr)* phdr,ElfW (Addr)seg_page_end,ElfW (Addr)seg_file_end)974 bool ElfReader::MapBssSection(const ElfW(Phdr)* phdr, ElfW(Addr) seg_page_end,
975                               ElfW(Addr) seg_file_end) {
976   // NOTE: We do not need to handle .bss in 16KiB compat mode since the mapping
977   // reservation is anonymous and RW to begin with.
978   if (should_use_16kib_app_compat_) {
979     return true;
980   }
981 
982   // seg_file_end is now the first page address after the file content.
983   seg_file_end = page_end(seg_file_end);
984 
985   if (seg_page_end <= seg_file_end) {
986     return true;
987   }
988 
989   // If seg_page_end is larger than seg_file_end, we need to zero
990   // anything between them. This is done by using a private anonymous
991   // map for all extra pages
992   size_t zeromap_size = seg_page_end - seg_file_end;
993   void* zeromap =
994       mmap(reinterpret_cast<void*>(seg_file_end), zeromap_size, PFLAGS_TO_PROT(phdr->p_flags),
995            MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
996   if (zeromap == MAP_FAILED) {
997     DL_ERR("couldn't map .bss section for \"%s\": %m", name_.c_str());
998     return false;
999   }
1000 
1001   // Set the VMA name using prctl
1002   prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, zeromap, zeromap_size, ".bss");
1003 
1004   return true;
1005 }
1006 
LoadSegments()1007 bool ElfReader::LoadSegments() {
1008   // NOTE: The compat(legacy) page size (4096) must be used when aligning
1009   // the 4KiB segments for loading in compat mode. The larger 16KiB page size
1010   // will lead to overwriting adjacent segments since the ELF's segment(s)
1011   // are not 16KiB aligned.
1012   size_t seg_align = should_use_16kib_app_compat_ ? kCompatPageSize : kPageSize;
1013 
1014   size_t min_palign = phdr_table_get_minimum_alignment(phdr_table_, phdr_num_);
1015   // Only enforce this on 16 KB systems with app compat disabled.
1016   // Apps may rely on undefined behavior here on 4 KB systems,
1017   // which is the norm before this change is introduced
1018   if (kPageSize >= 16384 && min_palign < kPageSize && !should_use_16kib_app_compat_) {
1019     DL_ERR("\"%s\" program alignment (%zu) cannot be smaller than system page size (%zu)",
1020            name_.c_str(), min_palign, kPageSize);
1021     return false;
1022   }
1023 
1024   if (!Setup16KiBAppCompat()) {
1025     DL_ERR("\"%s\" failed to setup 16KiB App Compat", name_.c_str());
1026     return false;
1027   }
1028 
1029   for (size_t i = 0; i < phdr_num_; ++i) {
1030     const ElfW(Phdr)* phdr = &phdr_table_[i];
1031 
1032     if (phdr->p_type != PT_LOAD) {
1033       continue;
1034     }
1035 
1036     ElfW(Addr) p_memsz = phdr->p_memsz;
1037     ElfW(Addr) p_filesz = phdr->p_filesz;
1038     _extend_load_segment_vma(phdr_table_, phdr_num_, i, &p_memsz, &p_filesz, should_pad_segments_,
1039                              should_use_16kib_app_compat_);
1040 
1041     // Segment addresses in memory.
1042     ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
1043     ElfW(Addr) seg_end = seg_start + p_memsz;
1044 
1045     ElfW(Addr) seg_page_end = align_up(seg_end, seg_align);
1046 
1047     ElfW(Addr) seg_file_end = seg_start + p_filesz;
1048 
1049     // File offsets.
1050     ElfW(Addr) file_start = phdr->p_offset;
1051     ElfW(Addr) file_end = file_start + p_filesz;
1052 
1053     ElfW(Addr) file_page_start = align_down(file_start, seg_align);
1054     ElfW(Addr) file_length = file_end - file_page_start;
1055 
1056     if (file_size_ <= 0) {
1057       DL_ERR("\"%s\" invalid file size: %" PRId64, name_.c_str(), file_size_);
1058       return false;
1059     }
1060 
1061     if (file_start + phdr->p_filesz > static_cast<size_t>(file_size_)) {
1062       DL_ERR("invalid ELF file \"%s\" load segment[%zd]:"
1063           " p_offset (%p) + p_filesz (%p) ( = %p) past end of file (0x%" PRIx64 ")",
1064           name_.c_str(), i, reinterpret_cast<void*>(phdr->p_offset),
1065           reinterpret_cast<void*>(phdr->p_filesz),
1066           reinterpret_cast<void*>(file_start + phdr->p_filesz), file_size_);
1067       return false;
1068     }
1069 
1070     if (file_length != 0) {
1071       int prot = PFLAGS_TO_PROT(phdr->p_flags);
1072       if ((prot & (PROT_EXEC | PROT_WRITE)) == (PROT_EXEC | PROT_WRITE)) {
1073         // W + E PT_LOAD segments are not allowed in O.
1074         if (get_application_target_sdk_version() >= 26) {
1075           DL_ERR_AND_LOG("\"%s\": W+E load segments are not allowed", name_.c_str());
1076           return false;
1077         }
1078         DL_WARN_documented_change(26,
1079                                   "writable-and-executable-segments-enforced-for-api-level-26",
1080                                   "\"%s\" has load segments that are both writable and executable",
1081                                   name_.c_str());
1082         add_dlwarning(name_.c_str(), "W+E load segments");
1083       }
1084 
1085       // Pass the file_length, since it may have been extended by _extend_load_segment_vma().
1086       if (should_use_16kib_app_compat_) {
1087         if (!CompatMapSegment(i, file_length)) {
1088           return false;
1089         }
1090       } else {
1091         if (!MapSegment(i, file_length)) {
1092           return false;
1093         }
1094       }
1095     }
1096 
1097     ZeroFillSegment(phdr);
1098 
1099     DropPaddingPages(phdr, seg_file_end);
1100 
1101     if (!MapBssSection(phdr, seg_page_end, seg_file_end)) {
1102       return false;
1103     }
1104   }
1105   return true;
1106 }
1107 
1108 /* Used internally. Used to set the protection bits of all loaded segments
1109  * with optional extra flags (i.e. really PROT_WRITE). Used by
1110  * phdr_table_protect_segments and phdr_table_unprotect_segments.
1111  */
_phdr_table_set_load_prot(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,int extra_prot_flags,bool should_pad_segments,bool should_use_16kib_app_compat)1112 static int _phdr_table_set_load_prot(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1113                                      ElfW(Addr) load_bias, int extra_prot_flags,
1114                                      bool should_pad_segments, bool should_use_16kib_app_compat) {
1115   for (size_t i = 0; i < phdr_count; ++i) {
1116     const ElfW(Phdr)* phdr = &phdr_table[i];
1117 
1118     if (phdr->p_type != PT_LOAD || (phdr->p_flags & PF_W) != 0) {
1119       continue;
1120     }
1121 
1122     ElfW(Addr) p_memsz = phdr->p_memsz;
1123     ElfW(Addr) p_filesz = phdr->p_filesz;
1124     _extend_load_segment_vma(phdr_table, phdr_count, i, &p_memsz, &p_filesz, should_pad_segments,
1125                              should_use_16kib_app_compat);
1126 
1127     ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr + load_bias);
1128     ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + p_memsz + load_bias);
1129 
1130     int prot = PFLAGS_TO_PROT(phdr->p_flags) | extra_prot_flags;
1131     if ((prot & PROT_WRITE) != 0) {
1132       // make sure we're never simultaneously writable / executable
1133       prot &= ~PROT_EXEC;
1134     }
1135 #if defined(__aarch64__)
1136     if ((prot & PROT_EXEC) == 0) {
1137       // Though it is not specified don't add PROT_BTI if segment is not
1138       // executable.
1139       prot &= ~PROT_BTI;
1140     }
1141 #endif
1142 
1143     int ret =
1144         mprotect(reinterpret_cast<void*>(seg_page_start), seg_page_end - seg_page_start, prot);
1145     if (ret < 0) {
1146       return -1;
1147     }
1148   }
1149   return 0;
1150 }
1151 
1152 /* Restore the original protection modes for all loadable segments.
1153  * You should only call this after phdr_table_unprotect_segments and
1154  * applying all relocations.
1155  *
1156  * AArch64: also called from linker_main and ElfReader::Load to apply
1157  *     PROT_BTI for loaded main so and other so-s.
1158  *
1159  * Input:
1160  *   phdr_table  -> program header table
1161  *   phdr_count  -> number of entries in tables
1162  *   load_bias   -> load bias
1163  *   should_pad_segments -> Are segments extended to avoid gaps in the memory map
1164  *   should_use_16kib_app_compat -> Is the ELF being loaded in 16KiB app compat mode.
1165  *   prop        -> GnuPropertySection or nullptr
1166  * Return:
1167  *   0 on success, -1 on failure (error code in errno).
1168  */
phdr_table_protect_segments(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,bool should_pad_segments,bool should_use_16kib_app_compat,const GnuPropertySection * prop __unused)1169 int phdr_table_protect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1170                                 ElfW(Addr) load_bias, bool should_pad_segments,
1171                                 bool should_use_16kib_app_compat,
1172                                 const GnuPropertySection* prop __unused) {
1173   int prot = 0;
1174 #if defined(__aarch64__)
1175   if ((prop != nullptr) && prop->IsBTICompatible()) {
1176     prot |= PROT_BTI;
1177   }
1178 #endif
1179   return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, prot, should_pad_segments,
1180                                    should_use_16kib_app_compat);
1181 }
1182 
segment_needs_memtag_globals_remapping(const ElfW (Phdr)* phdr)1183 static bool segment_needs_memtag_globals_remapping(const ElfW(Phdr) * phdr) {
1184   // For now, MTE globals is only supported on writeable data segments.
1185   return phdr->p_type == PT_LOAD && !(phdr->p_flags & PF_X) && (phdr->p_flags & PF_W);
1186 }
1187 
1188 /* When MTE globals are requested by the binary, and when the hardware supports
1189  * it, remap the executable's PT_LOAD data pages to have PROT_MTE.
1190  *
1191  * Returns 0 on success, -1 on failure (error code in errno).
1192  */
remap_memtag_globals_segments(const ElfW (Phdr)* phdr_table __unused,size_t phdr_count __unused,ElfW (Addr)load_bias __unused)1193 int remap_memtag_globals_segments(const ElfW(Phdr) * phdr_table __unused,
1194                                   size_t phdr_count __unused, ElfW(Addr) load_bias __unused) {
1195 #if defined(__aarch64__)
1196   for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_table + phdr_count; phdr++) {
1197     if (!segment_needs_memtag_globals_remapping(phdr)) {
1198       continue;
1199     }
1200 
1201     uintptr_t seg_page_start = page_start(phdr->p_vaddr) + load_bias;
1202     uintptr_t seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
1203     size_t seg_page_aligned_size = seg_page_end - seg_page_start;
1204 
1205     int prot = PFLAGS_TO_PROT(phdr->p_flags);
1206     // For anonymous private mappings, it may be possible to simply mprotect()
1207     // the PROT_MTE flag over the top. For file-based mappings, this will fail,
1208     // and we'll need to fall back. We also allow PROT_WRITE here to allow
1209     // writing memory tags (in `soinfo::tag_globals()`), and set these sections
1210     // back to read-only after tags are applied (similar to RELRO).
1211     prot |= PROT_MTE;
1212     if (mprotect(reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size,
1213                  prot | PROT_WRITE) == 0) {
1214       continue;
1215     }
1216 
1217     void* mapping_copy = mmap(nullptr, seg_page_aligned_size, PROT_READ | PROT_WRITE,
1218                               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
1219     linker_memcpy(mapping_copy, reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size);
1220 
1221     void* seg_addr = mmap(reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size,
1222                           prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
1223     if (seg_addr == MAP_FAILED) return -1;
1224 
1225     linker_memcpy(seg_addr, mapping_copy, seg_page_aligned_size);
1226     munmap(mapping_copy, seg_page_aligned_size);
1227   }
1228 #endif  // defined(__aarch64__)
1229   return 0;
1230 }
1231 
protect_memtag_globals_ro_segments(const ElfW (Phdr)* phdr_table __unused,size_t phdr_count __unused,ElfW (Addr)load_bias __unused)1232 void protect_memtag_globals_ro_segments(const ElfW(Phdr) * phdr_table __unused,
1233                                         size_t phdr_count __unused, ElfW(Addr) load_bias __unused) {
1234 #if defined(__aarch64__)
1235   for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_table + phdr_count; phdr++) {
1236     int prot = PFLAGS_TO_PROT(phdr->p_flags);
1237     if (!segment_needs_memtag_globals_remapping(phdr) || (prot & PROT_WRITE)) {
1238       continue;
1239     }
1240 
1241     prot |= PROT_MTE;
1242 
1243     uintptr_t seg_page_start = page_start(phdr->p_vaddr) + load_bias;
1244     uintptr_t seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
1245     size_t seg_page_aligned_size = seg_page_end - seg_page_start;
1246     mprotect(reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size, prot);
1247   }
1248 #endif  // defined(__aarch64__)
1249 }
1250 
name_memtag_globals_segments(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,const char * soname,std::list<std::string> * vma_names)1251 void name_memtag_globals_segments(const ElfW(Phdr) * phdr_table, size_t phdr_count,
1252                                   ElfW(Addr) load_bias, const char* soname,
1253                                   std::list<std::string>* vma_names) {
1254   for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_table + phdr_count; phdr++) {
1255     if (!segment_needs_memtag_globals_remapping(phdr)) {
1256       continue;
1257     }
1258 
1259     uintptr_t seg_page_start = page_start(phdr->p_vaddr) + load_bias;
1260     uintptr_t seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
1261     size_t seg_page_aligned_size = seg_page_end - seg_page_start;
1262 
1263     // For file-based mappings that we're now forcing to be anonymous mappings, set the VMA name to
1264     // make debugging easier.
1265     // Once we are targeting only devices that run kernel 5.10 or newer (and thus include
1266     // https://android-review.git.corp.google.com/c/kernel/common/+/1934723 which causes the
1267     // VMA_ANON_NAME to be copied into the kernel), we can get rid of the storage here.
1268     // For now, that is not the case:
1269     // https://source.android.com/docs/core/architecture/kernel/android-common#compatibility-matrix
1270     constexpr int kVmaNameLimit = 80;
1271     std::string& vma_name = vma_names->emplace_back(kVmaNameLimit, '\0');
1272     int full_vma_length =
1273         async_safe_format_buffer(vma_name.data(), kVmaNameLimit, "mt:%s+%" PRIxPTR, soname,
1274                                  page_start(phdr->p_vaddr)) +
1275         /* include the null terminator */ 1;
1276     // There's an upper limit of 80 characters, including the null terminator, in the anonymous VMA
1277     // name. If we run over that limit, we end up truncating the segment offset and parts of the
1278     // DSO's name, starting on the right hand side of the basename. Because the basename is the most
1279     // important thing, chop off the soname from the left hand side first.
1280     //
1281     // Example (with '#' as the null terminator):
1282     //   - "mt:/data/nativetest64/bionic-unit-tests/bionic-loader-test-libs/libdlext_test.so+e000#"
1283     //     is a `full_vma_length` == 86.
1284     //
1285     // We need to left-truncate (86 - 80) 6 characters from the soname, plus the
1286     // `vma_truncation_prefix`, so 9 characters total.
1287     if (full_vma_length > kVmaNameLimit) {
1288       const char vma_truncation_prefix[] = "...";
1289       int soname_truncated_bytes =
1290           full_vma_length - kVmaNameLimit + sizeof(vma_truncation_prefix) - 1;
1291       async_safe_format_buffer(vma_name.data(), kVmaNameLimit, "mt:%s%s+%" PRIxPTR,
1292                                vma_truncation_prefix, soname + soname_truncated_bytes,
1293                                page_start(phdr->p_vaddr));
1294     }
1295     if (prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, reinterpret_cast<void*>(seg_page_start),
1296               seg_page_aligned_size, vma_name.data()) != 0) {
1297       DL_WARN("Failed to rename memtag global segment: %m");
1298     }
1299   }
1300 }
1301 
1302 /* Change the protection of all loaded segments in memory to writable.
1303  * This is useful before performing relocations. Once completed, you
1304  * will have to call phdr_table_protect_segments to restore the original
1305  * protection flags on all segments.
1306  *
1307  * Note that some writable segments can also have their content turned
1308  * to read-only by calling phdr_table_protect_gnu_relro. This is no
1309  * performed here.
1310  *
1311  * Input:
1312  *   phdr_table  -> program header table
1313  *   phdr_count  -> number of entries in tables
1314  *   load_bias   -> load bias
1315  *   should_pad_segments -> Are segments extended to avoid gaps in the memory map
1316  *   should_use_16kib_app_compat -> Is the ELF being loaded in 16KiB app compat mode.
1317  * Return:
1318  *   0 on success, -1 on failure (error code in errno).
1319  */
phdr_table_unprotect_segments(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,bool should_pad_segments,bool should_use_16kib_app_compat)1320 int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1321                                   ElfW(Addr) load_bias, bool should_pad_segments,
1322                                   bool should_use_16kib_app_compat) {
1323   return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, PROT_WRITE,
1324                                    should_pad_segments, should_use_16kib_app_compat);
1325 }
1326 
_extend_gnu_relro_prot_end(const ElfW (Phdr)* relro_phdr,const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,ElfW (Addr)* seg_page_end,bool should_pad_segments,bool should_use_16kib_app_compat)1327 static inline void _extend_gnu_relro_prot_end(const ElfW(Phdr)* relro_phdr,
1328                                               const ElfW(Phdr)* phdr_table, size_t phdr_count,
1329                                               ElfW(Addr) load_bias, ElfW(Addr)* seg_page_end,
1330                                               bool should_pad_segments,
1331                                               bool should_use_16kib_app_compat) {
1332   // Find the index and phdr of the LOAD containing the GNU_RELRO segment
1333   for (size_t index = 0; index < phdr_count; ++index) {
1334     const ElfW(Phdr)* phdr = &phdr_table[index];
1335 
1336     if (phdr->p_type == PT_LOAD && phdr->p_vaddr == relro_phdr->p_vaddr) {
1337       // If the PT_GNU_RELRO mem size is not at least as large as the corresponding
1338       // LOAD segment mem size, we need to protect only a partial region of the
1339       // LOAD segment and therefore cannot avoid a VMA split.
1340       //
1341       // Note: Don't check the page-aligned mem sizes since the extended protection
1342       // may incorrectly write protect non-relocation data.
1343       //
1344       // Example:
1345       //
1346       //               |---- 3K ----|-- 1K --|---- 3K ---- |-- 1K --|
1347       //       ----------------------------------------------------------------
1348       //               |            |        |             |        |
1349       //        SEG X  |     RO     |   RO   |     RW      |        |   SEG Y
1350       //               |            |        |             |        |
1351       //       ----------------------------------------------------------------
1352       //                            |        |             |
1353       //                            |        |             |
1354       //                            |        |             |
1355       //                    relro_vaddr   relro_vaddr   relro_vaddr
1356       //                    (load_vaddr)       +            +
1357       //                                  relro_memsz   load_memsz
1358       //
1359       //       ----------------------------------------------------------------
1360       //               |         PAGE        |         PAGE         |
1361       //       ----------------------------------------------------------------
1362       //                                     |       Potential      |
1363       //                                     |----- Extended RO ----|
1364       //                                     |      Protection      |
1365       //
1366       // If the check below uses  page aligned mem sizes it will cause incorrect write
1367       // protection of the 3K RW part of the LOAD segment containing the GNU_RELRO.
1368       if (relro_phdr->p_memsz < phdr->p_memsz) {
1369         return;
1370       }
1371 
1372       ElfW(Addr) p_memsz = phdr->p_memsz;
1373       ElfW(Addr) p_filesz = phdr->p_filesz;
1374 
1375       // Attempt extending the VMA (mprotect range). Without extending the range,
1376       // mprotect will only RO protect a part of the extended RW LOAD segment, which
1377       // will leave an extra split RW VMA (the gap).
1378       _extend_load_segment_vma(phdr_table, phdr_count, index, &p_memsz, &p_filesz,
1379                                should_pad_segments, should_use_16kib_app_compat);
1380 
1381       *seg_page_end = page_end(phdr->p_vaddr + p_memsz + load_bias);
1382       return;
1383     }
1384   }
1385 }
1386 
1387 /* Used internally by phdr_table_protect_gnu_relro and
1388  * phdr_table_unprotect_gnu_relro.
1389  */
_phdr_table_set_gnu_relro_prot(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,int prot_flags,bool should_pad_segments,bool should_use_16kib_app_compat)1390 static int _phdr_table_set_gnu_relro_prot(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1391                                           ElfW(Addr) load_bias, int prot_flags,
1392                                           bool should_pad_segments,
1393                                           bool should_use_16kib_app_compat) {
1394   const ElfW(Phdr)* phdr = phdr_table;
1395   const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
1396 
1397   for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
1398     if (phdr->p_type != PT_GNU_RELRO) {
1399       continue;
1400     }
1401 
1402     // Tricky: what happens when the relro segment does not start
1403     // or end at page boundaries? We're going to be over-protective
1404     // here and put every page touched by the segment as read-only.
1405 
1406     // This seems to match Ian Lance Taylor's description of the
1407     // feature at http://www.airs.com/blog/archives/189.
1408 
1409     //    Extract:
1410     //       Note that the current dynamic linker code will only work
1411     //       correctly if the PT_GNU_RELRO segment starts on a page
1412     //       boundary. This is because the dynamic linker rounds the
1413     //       p_vaddr field down to the previous page boundary. If
1414     //       there is anything on the page which should not be read-only,
1415     //       the program is likely to fail at runtime. So in effect the
1416     //       linker must only emit a PT_GNU_RELRO segment if it ensures
1417     //       that it starts on a page boundary.
1418     ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
1419     ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
1420     _extend_gnu_relro_prot_end(phdr, phdr_table, phdr_count, load_bias, &seg_page_end,
1421                                should_pad_segments, should_use_16kib_app_compat);
1422 
1423     int ret = mprotect(reinterpret_cast<void*>(seg_page_start),
1424                        seg_page_end - seg_page_start,
1425                        prot_flags);
1426     if (ret < 0) {
1427       return -1;
1428     }
1429   }
1430   return 0;
1431 }
1432 
1433 /* Apply GNU relro protection if specified by the program header. This will
1434  * turn some of the pages of a writable PT_LOAD segment to read-only, as
1435  * specified by one or more PT_GNU_RELRO segments. This must be always
1436  * performed after relocations.
1437  *
1438  * The areas typically covered are .got and .data.rel.ro, these are
1439  * read-only from the program's POV, but contain absolute addresses
1440  * that need to be relocated before use.
1441  *
1442  * Input:
1443  *   phdr_table  -> program header table
1444  *   phdr_count  -> number of entries in tables
1445  *   load_bias   -> load bias
1446  *   should_pad_segments -> Were segments extended to avoid gaps in the memory map
1447  *   should_use_16kib_app_compat -> Is the ELF being loaded in 16KiB app compat mode.
1448  * Return:
1449  *   0 on success, -1 on failure (error code in errno).
1450  */
phdr_table_protect_gnu_relro(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,bool should_pad_segments,bool should_use_16kib_app_compat)1451 int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1452                                  ElfW(Addr) load_bias, bool should_pad_segments,
1453                                  bool should_use_16kib_app_compat) {
1454   return _phdr_table_set_gnu_relro_prot(phdr_table, phdr_count, load_bias, PROT_READ,
1455                                         should_pad_segments, should_use_16kib_app_compat);
1456 }
1457 
1458 /*
1459  * Apply RX protection to the compat relro region of the ELF being loaded in
1460  * 16KiB compat mode.
1461  *
1462  * Input:
1463  *   start  -> start address of the compat relro region.
1464  *   size   -> size of the compat relro region in bytes.
1465  * Return:
1466  *   0 on success, -1 on failure (error code in errno).
1467  */
phdr_table_protect_gnu_relro_16kib_compat(ElfW (Addr)start,ElfW (Addr)size)1468 int phdr_table_protect_gnu_relro_16kib_compat(ElfW(Addr) start, ElfW(Addr) size) {
1469   return mprotect(reinterpret_cast<void*>(start), size, PROT_READ | PROT_EXEC);
1470 }
1471 
1472 /* Serialize the GNU relro segments to the given file descriptor. This can be
1473  * performed after relocations to allow another process to later share the
1474  * relocated segment, if it was loaded at the same address.
1475  *
1476  * Input:
1477  *   phdr_table  -> program header table
1478  *   phdr_count  -> number of entries in tables
1479  *   load_bias   -> load bias
1480  *   fd          -> writable file descriptor to use
1481  *   file_offset -> pointer to offset into file descriptor to use/update
1482  * Return:
1483  *   0 on success, -1 on failure (error code in errno).
1484  */
phdr_table_serialize_gnu_relro(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,int fd,size_t * file_offset)1485 int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table,
1486                                    size_t phdr_count,
1487                                    ElfW(Addr) load_bias,
1488                                    int fd,
1489                                    size_t* file_offset) {
1490   const ElfW(Phdr)* phdr = phdr_table;
1491   const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
1492 
1493   for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
1494     if (phdr->p_type != PT_GNU_RELRO) {
1495       continue;
1496     }
1497 
1498     ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
1499     ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
1500     ssize_t size = seg_page_end - seg_page_start;
1501 
1502     ssize_t written = TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<void*>(seg_page_start), size));
1503     if (written != size) {
1504       return -1;
1505     }
1506     void* map = mmap(reinterpret_cast<void*>(seg_page_start), size, PROT_READ,
1507                      MAP_PRIVATE|MAP_FIXED, fd, *file_offset);
1508     if (map == MAP_FAILED) {
1509       return -1;
1510     }
1511     *file_offset += size;
1512   }
1513   return 0;
1514 }
1515 
1516 /* Where possible, replace the GNU relro segments with mappings of the given
1517  * file descriptor. This can be performed after relocations to allow a file
1518  * previously created by phdr_table_serialize_gnu_relro in another process to
1519  * replace the dirty relocated pages, saving memory, if it was loaded at the
1520  * same address. We have to compare the data before we map over it, since some
1521  * parts of the relro segment may not be identical due to other libraries in
1522  * the process being loaded at different addresses.
1523  *
1524  * Input:
1525  *   phdr_table  -> program header table
1526  *   phdr_count  -> number of entries in tables
1527  *   load_bias   -> load bias
1528  *   fd          -> readable file descriptor to use
1529  *   file_offset -> pointer to offset into file descriptor to use/update
1530  * Return:
1531  *   0 on success, -1 on failure (error code in errno).
1532  */
phdr_table_map_gnu_relro(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias,int fd,size_t * file_offset)1533 int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table,
1534                              size_t phdr_count,
1535                              ElfW(Addr) load_bias,
1536                              int fd,
1537                              size_t* file_offset) {
1538   // Map the file at a temporary location so we can compare its contents.
1539   struct stat file_stat;
1540   if (TEMP_FAILURE_RETRY(fstat(fd, &file_stat)) != 0) {
1541     return -1;
1542   }
1543   off_t file_size = file_stat.st_size;
1544   void* temp_mapping = nullptr;
1545   if (file_size > 0) {
1546     temp_mapping = mmap(nullptr, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
1547     if (temp_mapping == MAP_FAILED) {
1548       return -1;
1549     }
1550   }
1551 
1552   // Iterate over the relro segments and compare/remap the pages.
1553   const ElfW(Phdr)* phdr = phdr_table;
1554   const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
1555 
1556   for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
1557     if (phdr->p_type != PT_GNU_RELRO) {
1558       continue;
1559     }
1560 
1561     ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
1562     ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
1563 
1564     char* file_base = static_cast<char*>(temp_mapping) + *file_offset;
1565     char* mem_base = reinterpret_cast<char*>(seg_page_start);
1566     size_t match_offset = 0;
1567     size_t size = seg_page_end - seg_page_start;
1568 
1569     if (file_size - *file_offset < size) {
1570       // File is too short to compare to this segment. The contents are likely
1571       // different as well (it's probably for a different library version) so
1572       // just don't bother checking.
1573       break;
1574     }
1575 
1576     while (match_offset < size) {
1577       // Skip over dissimilar pages.
1578       while (match_offset < size &&
1579              memcmp(mem_base + match_offset, file_base + match_offset, page_size()) != 0) {
1580         match_offset += page_size();
1581       }
1582 
1583       // Count similar pages.
1584       size_t mismatch_offset = match_offset;
1585       while (mismatch_offset < size &&
1586              memcmp(mem_base + mismatch_offset, file_base + mismatch_offset, page_size()) == 0) {
1587         mismatch_offset += page_size();
1588       }
1589 
1590       // Map over similar pages.
1591       if (mismatch_offset > match_offset) {
1592         void* map = mmap(mem_base + match_offset, mismatch_offset - match_offset,
1593                          PROT_READ, MAP_PRIVATE|MAP_FIXED, fd, *file_offset + match_offset);
1594         if (map == MAP_FAILED) {
1595           munmap(temp_mapping, file_size);
1596           return -1;
1597         }
1598       }
1599 
1600       match_offset = mismatch_offset;
1601     }
1602 
1603     // Add to the base file offset in case there are multiple relro segments.
1604     *file_offset += size;
1605   }
1606   munmap(temp_mapping, file_size);
1607   return 0;
1608 }
1609 
1610 
1611 #if defined(__arm__)
1612 /* Return the address and size of the .ARM.exidx section in memory,
1613  * if present.
1614  *
1615  * Input:
1616  *   phdr_table  -> program header table
1617  *   phdr_count  -> number of entries in tables
1618  *   load_bias   -> load bias
1619  * Output:
1620  *   arm_exidx       -> address of table in memory (null on failure).
1621  *   arm_exidx_count -> number of items in table (0 on failure).
1622  * Return:
1623  *   0 on success, -1 on failure (_no_ error code in errno)
1624  */
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)1625 int phdr_table_get_arm_exidx(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1626                              ElfW(Addr) load_bias,
1627                              ElfW(Addr)** arm_exidx, size_t* arm_exidx_count) {
1628   const ElfW(Phdr)* phdr = phdr_table;
1629   const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
1630 
1631   for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
1632     if (phdr->p_type != PT_ARM_EXIDX) {
1633       continue;
1634     }
1635 
1636     *arm_exidx = reinterpret_cast<ElfW(Addr)*>(load_bias + phdr->p_vaddr);
1637     *arm_exidx_count = phdr->p_memsz / 8;
1638     return 0;
1639   }
1640   *arm_exidx = nullptr;
1641   *arm_exidx_count = 0;
1642   return -1;
1643 }
1644 #endif
1645 
1646 /* Return the address and size of the ELF file's .dynamic section in memory,
1647  * or null if missing.
1648  *
1649  * Input:
1650  *   phdr_table  -> program header table
1651  *   phdr_count  -> number of entries in tables
1652  *   load_bias   -> load bias
1653  * Output:
1654  *   dynamic       -> address of table in memory (null on failure).
1655  *   dynamic_flags -> protection flags for section (unset on failure)
1656  * Return:
1657  *   void
1658  */
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)1659 void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1660                                     ElfW(Addr) load_bias, ElfW(Dyn)** dynamic,
1661                                     ElfW(Word)* dynamic_flags) {
1662   *dynamic = nullptr;
1663   for (size_t i = 0; i<phdr_count; ++i) {
1664     const ElfW(Phdr)& phdr = phdr_table[i];
1665     if (phdr.p_type == PT_DYNAMIC) {
1666       *dynamic = reinterpret_cast<ElfW(Dyn)*>(load_bias + phdr.p_vaddr);
1667       if (dynamic_flags) {
1668         *dynamic_flags = phdr.p_flags;
1669       }
1670       return;
1671     }
1672   }
1673 }
1674 
1675 /* Return the program interpreter string, or nullptr if missing.
1676  *
1677  * Input:
1678  *   phdr_table  -> program header table
1679  *   phdr_count  -> number of entries in tables
1680  *   load_bias   -> load bias
1681  * Return:
1682  *   pointer to the program interpreter string.
1683  */
phdr_table_get_interpreter_name(const ElfW (Phdr)* phdr_table,size_t phdr_count,ElfW (Addr)load_bias)1684 const char* phdr_table_get_interpreter_name(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1685                                             ElfW(Addr) load_bias) {
1686   for (size_t i = 0; i<phdr_count; ++i) {
1687     const ElfW(Phdr)& phdr = phdr_table[i];
1688     if (phdr.p_type == PT_INTERP) {
1689       return reinterpret_cast<const char*>(load_bias + phdr.p_vaddr);
1690     }
1691   }
1692   return nullptr;
1693 }
1694 
1695 // Sets loaded_phdr_ to the address of the program header table as it appears
1696 // in the loaded segments in memory. This is in contrast with phdr_table_,
1697 // which is temporary and will be released before the library is relocated.
FindPhdr()1698 bool ElfReader::FindPhdr() {
1699   const ElfW(Phdr)* phdr_limit = phdr_table_ + phdr_num_;
1700 
1701   // If there is a PT_PHDR, use it directly.
1702   for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
1703     if (phdr->p_type == PT_PHDR) {
1704       return CheckPhdr(load_bias_ + phdr->p_vaddr);
1705     }
1706   }
1707 
1708   // Otherwise, check the first loadable segment. If its file offset
1709   // is 0, it starts with the ELF header, and we can trivially find the
1710   // loaded program header from it.
1711   for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
1712     if (phdr->p_type == PT_LOAD) {
1713       if (phdr->p_offset == 0) {
1714         ElfW(Addr)  elf_addr = load_bias_ + phdr->p_vaddr;
1715         const ElfW(Ehdr)* ehdr = reinterpret_cast<const ElfW(Ehdr)*>(elf_addr);
1716         ElfW(Addr)  offset = ehdr->e_phoff;
1717         return CheckPhdr(reinterpret_cast<ElfW(Addr)>(ehdr) + offset);
1718       }
1719       break;
1720     }
1721   }
1722 
1723   DL_ERR("can't find loaded phdr for \"%s\"", name_.c_str());
1724   return false;
1725 }
1726 
1727 // Tries to find .note.gnu.property section.
1728 // It is not considered an error if such section is missing.
FindGnuPropertySection()1729 bool ElfReader::FindGnuPropertySection() {
1730 #if defined(__aarch64__)
1731   note_gnu_property_ = GnuPropertySection(phdr_table_, phdr_num_, load_start(), name_.c_str());
1732 #endif
1733   return true;
1734 }
1735 
1736 // Ensures that our program header is actually within a loadable
1737 // segment. This should help catch badly-formed ELF files that
1738 // would cause the linker to crash later when trying to access it.
CheckPhdr(ElfW (Addr)loaded)1739 bool ElfReader::CheckPhdr(ElfW(Addr) loaded) {
1740   const ElfW(Phdr)* phdr_limit = phdr_table_ + phdr_num_;
1741   ElfW(Addr) loaded_end = loaded + (phdr_num_ * sizeof(ElfW(Phdr)));
1742   for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
1743     if (phdr->p_type != PT_LOAD) {
1744       continue;
1745     }
1746     ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
1747     ElfW(Addr) seg_end = phdr->p_filesz + seg_start;
1748     if (seg_start <= loaded && loaded_end <= seg_end) {
1749       loaded_phdr_ = reinterpret_cast<const ElfW(Phdr)*>(loaded);
1750       return true;
1751     }
1752   }
1753   DL_ERR("\"%s\" loaded phdr %p not in loadable segment",
1754          name_.c_str(), reinterpret_cast<void*>(loaded));
1755   return false;
1756 }
1757