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_, ¬e_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, ¬e_hdr, ¬e_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