1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #include <string>
6 #include <cstring>
7 #include <cstdlib>
8 #include <cstdio>
9 #include <dlfcn.h>
10 #include <unistd.h>
11 #include <errno.h>
12 #include <algorithm>
13 #include <fcntl.h>
14 #include "ElfLoader.h"
15 #include "BaseElf.h"
16 #include "CustomElf.h"
17 #include "Mappable.h"
18 #include "Logging.h"
19 #include "Utils.h"
20 #include <inttypes.h>
21 
22 // From Utils.h
23 mozilla::Atomic<size_t, mozilla::ReleaseAcquire> gPageSize;
24 
25 #if defined(ANDROID)
26 #  include <sys/syscall.h>
27 #  include <sys/system_properties.h>
28 #  include <math.h>
29 
30 #  include <android/api-level.h>
31 
32 /**
33  * Return the current Android version, or 0 on failure.
34  */
GetAndroidSDKVersion()35 static int GetAndroidSDKVersion() {
36   static int version = 0;
37   if (version) {
38     return version;
39   }
40 
41   char version_string[PROP_VALUE_MAX] = {'\0'};
42   int len = __system_property_get("ro.build.version.sdk", version_string);
43   if (len) {
44     version = static_cast<int>(strtol(version_string, nullptr, 10));
45   }
46   return version;
47 }
48 
49 #  if __ANDROID_API__ < 8
50 /* Android API < 8 doesn't provide sigaltstack */
51 
52 extern "C" {
53 
sigaltstack(const stack_t * ss,stack_t * oss)54 inline int sigaltstack(const stack_t* ss, stack_t* oss) {
55   return syscall(__NR_sigaltstack, ss, oss);
56 }
57 
58 } /* extern "C" */
59 #  endif /* __ANDROID_API__ */
60 #endif   /* ANDROID */
61 
62 #ifdef __ARM_EABI__
63 extern "C" MOZ_EXPORT const void* __gnu_Unwind_Find_exidx(void* pc, int* pcount)
64     __attribute__((weak));
65 #endif
66 
67 /* Ideally we'd #include <link.h>, but that's a world of pain
68  * Moreover, not all versions of android support it, so we need a weak
69  * reference. */
70 extern "C" MOZ_EXPORT int dl_iterate_phdr(dl_phdr_cb callback, void* data)
71     __attribute__((weak));
72 
73 /* Pointer to the PT_DYNAMIC section of the executable or library
74  * containing this code. */
75 extern "C" Elf::Dyn _DYNAMIC[];
76 
77 /**
78  * dlfcn.h replacements functions
79  */
80 
__wrap_dlopen(const char * path,int flags)81 void* __wrap_dlopen(const char* path, int flags) {
82 #if defined(ANDROID)
83   if (GetAndroidSDKVersion() >= 23) {
84     return dlopen(path, flags);
85   }
86 #endif
87 
88   RefPtr<LibHandle> handle = ElfLoader::Singleton.Load(path, flags);
89   if (handle) handle->AddDirectRef();
90   return handle;
91 }
92 
__wrap_dlerror(void)93 const char* __wrap_dlerror(void) {
94 #if defined(ANDROID)
95   if (GetAndroidSDKVersion() >= 23) {
96     return dlerror();
97   }
98 #endif
99 
100   const char* error = ElfLoader::Singleton.lastError.exchange(nullptr);
101   if (error) {
102     // Return a custom error if available.
103     return error;
104   }
105   // Or fallback to the system error.
106   return dlerror();
107 }
108 
__wrap_dlsym(void * handle,const char * symbol)109 void* __wrap_dlsym(void* handle, const char* symbol) {
110 #if defined(ANDROID)
111   if (GetAndroidSDKVersion() >= 23) {
112     return dlsym(handle, symbol);
113   }
114 #endif
115 
116   if (!handle) {
117     ElfLoader::Singleton.lastError = "dlsym(NULL, sym) unsupported";
118     return nullptr;
119   }
120   if (handle != RTLD_DEFAULT && handle != RTLD_NEXT) {
121     LibHandle* h = reinterpret_cast<LibHandle*>(handle);
122     return h->GetSymbolPtr(symbol);
123   }
124 
125   ElfLoader::Singleton.lastError = nullptr;  // Use system dlerror.
126   return dlsym(handle, symbol);
127 }
128 
__wrap_dlclose(void * handle)129 int __wrap_dlclose(void* handle) {
130 #if defined(ANDROID)
131   if (GetAndroidSDKVersion() >= 23) {
132     return dlclose(handle);
133   }
134 #endif
135 
136   if (!handle) {
137     ElfLoader::Singleton.lastError = "No handle given to dlclose()";
138     return -1;
139   }
140   reinterpret_cast<LibHandle*>(handle)->ReleaseDirectRef();
141   return 0;
142 }
143 
__wrap_dladdr(const void * addr,Dl_info * info)144 int __wrap_dladdr(const void* addr, Dl_info* info) {
145 #if defined(ANDROID)
146   if (GetAndroidSDKVersion() >= 23) {
147     return dladdr(addr, info);
148   }
149 #endif
150 
151   RefPtr<LibHandle> handle =
152       ElfLoader::Singleton.GetHandleByPtr(const_cast<void*>(addr));
153   if (!handle) {
154     return dladdr(addr, info);
155   }
156   info->dli_fname = handle->GetPath();
157   info->dli_fbase = handle->GetBase();
158   return 1;
159 }
160 
161 class DlIteratePhdrHelper {
162  public:
DlIteratePhdrHelper()163   DlIteratePhdrHelper() {
164     int pipefd[2];
165     valid_pipe = (pipe(pipefd) == 0);
166     read_fd.reset(pipefd[0]);
167     write_fd.reset(pipefd[1]);
168   }
169 
170   int fill_and_call(dl_phdr_cb callback, const void* l_addr, const char* l_name,
171                     void* data);
172 
173  private:
174   bool valid_pipe;
175   AutoCloseFD read_fd;
176   AutoCloseFD write_fd;
177 };
178 
179 // This function is called for each shared library iterated over by
180 // dl_iterate_phdr, and is used to fill a dl_phdr_info which is then
181 // sent through to the dl_iterate_phdr callback.
fill_and_call(dl_phdr_cb callback,const void * l_addr,const char * l_name,void * data)182 int DlIteratePhdrHelper::fill_and_call(dl_phdr_cb callback, const void* l_addr,
183                                        const char* l_name, void* data) {
184   dl_phdr_info info;
185   info.dlpi_addr = reinterpret_cast<Elf::Addr>(l_addr);
186   info.dlpi_name = l_name;
187   info.dlpi_phdr = nullptr;
188   info.dlpi_phnum = 0;
189 
190   // Assuming l_addr points to Elf headers (in most cases, this is true),
191   // get the Phdr location from there.
192   // Unfortunately, when l_addr doesn't point to Elf headers, it may point
193   // to unmapped memory, or worse, unreadable memory. The only way to detect
194   // the latter without causing a SIGSEGV is to use the pointer in a system
195   // call that will try to read from there, and return an EFAULT error if
196   // it can't. One such system call is write(). It used to be possible to
197   // use a file descriptor on /dev/null for these kind of things, but recent
198   // Linux kernels never return an EFAULT error when using /dev/null.
199   // So instead, we use a self pipe. We do however need to read() from the
200   // read end of the pipe as well so as to not fill up the pipe buffer and
201   // block on subsequent writes.
202   // In the unlikely event reads from or write to the pipe fail for some
203   // other reason than EFAULT, we don't try any further and just skip setting
204   // the Phdr location for all subsequent libraries, rather than trying to
205   // start over with a new pipe.
206   int can_read = true;
207   if (valid_pipe) {
208     int ret;
209     char raw_ehdr[sizeof(Elf::Ehdr)];
210     static_assert(sizeof(raw_ehdr) < PIPE_BUF, "PIPE_BUF is too small");
211     do {
212       // writes are atomic when smaller than PIPE_BUF, per POSIX.1-2008.
213       ret = write(write_fd, l_addr, sizeof(raw_ehdr));
214     } while (ret == -1 && errno == EINTR);
215     if (ret != sizeof(raw_ehdr)) {
216       if (ret == -1 && errno == EFAULT) {
217         can_read = false;
218       } else {
219         valid_pipe = false;
220       }
221     } else {
222       size_t nbytes = 0;
223       do {
224         // Per POSIX.1-2008, interrupted reads can return a length smaller
225         // than the given one instead of failing with errno EINTR.
226         ret = read(read_fd, raw_ehdr + nbytes, sizeof(raw_ehdr) - nbytes);
227         if (ret > 0) nbytes += ret;
228       } while ((nbytes != sizeof(raw_ehdr) && ret > 0) ||
229                (ret == -1 && errno == EINTR));
230       if (nbytes != sizeof(raw_ehdr)) {
231         valid_pipe = false;
232       }
233     }
234   }
235 
236   if (valid_pipe && can_read) {
237     const Elf::Ehdr* ehdr = Elf::Ehdr::validate(l_addr);
238     if (ehdr) {
239       info.dlpi_phdr = reinterpret_cast<const Elf::Phdr*>(
240           reinterpret_cast<const char*>(ehdr) + ehdr->e_phoff);
241       info.dlpi_phnum = ehdr->e_phnum;
242     }
243   }
244 
245   return callback(&info, sizeof(dl_phdr_info), data);
246 }
247 
__wrap_dl_iterate_phdr(dl_phdr_cb callback,void * data)248 int __wrap_dl_iterate_phdr(dl_phdr_cb callback, void* data) {
249 #if defined(ANDROID)
250   if (GetAndroidSDKVersion() >= 23) {
251     return dl_iterate_phdr(callback, data);
252   }
253 #endif
254 
255   DlIteratePhdrHelper helper;
256   AutoLock lock(&ElfLoader::Singleton.handlesMutex);
257 
258   if (dl_iterate_phdr) {
259     for (ElfLoader::LibHandleList::reverse_iterator it =
260              ElfLoader::Singleton.handles.rbegin();
261          it < ElfLoader::Singleton.handles.rend(); ++it) {
262       BaseElf* elf = (*it)->AsBaseElf();
263       if (!elf) {
264         continue;
265       }
266       int ret = helper.fill_and_call(callback, (*it)->GetBase(),
267                                      (*it)->GetPath(), data);
268       if (ret) return ret;
269     }
270     return dl_iterate_phdr(callback, data);
271   }
272 
273   /* For versions of Android that don't support dl_iterate_phdr (< 5.0),
274    * we go through the debugger helper data, which is known to be racy, but
275    * there's not much we can do about this :( . */
276   if (!ElfLoader::Singleton.dbg) return -1;
277 
278   for (ElfLoader::DebuggerHelper::iterator it =
279            ElfLoader::Singleton.dbg.begin();
280        it < ElfLoader::Singleton.dbg.end(); ++it) {
281     int ret = helper.fill_and_call(callback, it->l_addr, it->l_name, data);
282     if (ret) return ret;
283   }
284   return 0;
285 }
286 
287 #ifdef __ARM_EABI__
__wrap___gnu_Unwind_Find_exidx(void * pc,int * pcount)288 const void* __wrap___gnu_Unwind_Find_exidx(void* pc, int* pcount) {
289   RefPtr<LibHandle> handle = ElfLoader::Singleton.GetHandleByPtr(pc);
290   if (handle) return handle->FindExidx(pcount);
291   if (__gnu_Unwind_Find_exidx) return __gnu_Unwind_Find_exidx(pc, pcount);
292   *pcount = 0;
293   return nullptr;
294 }
295 #endif
296 
297 /**
298  * faulty.lib public API
299  */
300 
__dl_get_mappable_length(void * handle)301 MFBT_API size_t __dl_get_mappable_length(void* handle) {
302   if (!handle) return 0;
303   return reinterpret_cast<LibHandle*>(handle)->GetMappableLength();
304 }
305 
__dl_mmap(void * handle,void * addr,size_t length,off_t offset)306 MFBT_API void* __dl_mmap(void* handle, void* addr, size_t length,
307                          off_t offset) {
308   if (!handle) return nullptr;
309   return reinterpret_cast<LibHandle*>(handle)->MappableMMap(addr, length,
310                                                             offset);
311 }
312 
__dl_munmap(void * handle,void * addr,size_t length)313 MFBT_API void __dl_munmap(void* handle, void* addr, size_t length) {
314   if (!handle) return;
315   return reinterpret_cast<LibHandle*>(handle)->MappableMUnmap(addr, length);
316 }
317 
IsSignalHandlingBroken()318 MFBT_API bool IsSignalHandlingBroken() {
319   return ElfLoader::Singleton.isSignalHandlingBroken();
320 }
321 
322 namespace {
323 
324 /**
325  * Returns the part after the last '/' for the given path
326  */
LeafName(const char * path)327 const char* LeafName(const char* path) {
328   const char* lastSlash = strrchr(path, '/');
329   if (lastSlash) return lastSlash + 1;
330   return path;
331 }
332 
333 /**
334  * Run the given lambda while holding the internal lock of the system linker.
335  * To take the lock, we call the system dl_iterate_phdr and invoke the lambda
336  * from the callback, which is called while the lock is held. Return true on
337  * success.
338  */
339 template <class Lambda>
RunWithSystemLinkerLock(Lambda && aLambda)340 static bool RunWithSystemLinkerLock(Lambda&& aLambda) {
341   if (!dl_iterate_phdr) {
342     // No dl_iterate_phdr support.
343     return false;
344   }
345 
346 #if defined(ANDROID)
347   if (GetAndroidSDKVersion() < 23) {
348     // dl_iterate_phdr is _not_ protected by a lock on Android < 23.
349     // Also return false here if we failed to get the version.
350     return false;
351   }
352 #endif
353 
354   dl_iterate_phdr(
355       [](dl_phdr_info*, size_t, void* lambda) -> int {
356         (*static_cast<Lambda*>(lambda))();
357         // Return 1 to stop iterating.
358         return 1;
359       },
360       &aLambda);
361   return true;
362 }
363 
364 } /* Anonymous namespace */
365 
366 /**
367  * LibHandle
368  */
~LibHandle()369 LibHandle::~LibHandle() { free(path); }
370 
GetName() const371 const char* LibHandle::GetName() const {
372   return path ? LeafName(path) : nullptr;
373 }
374 
GetMappableLength() const375 size_t LibHandle::GetMappableLength() const {
376   if (!mappable) mappable = GetMappable();
377   if (!mappable) return 0;
378   return mappable->GetLength();
379 }
380 
MappableMMap(void * addr,size_t length,off_t offset) const381 void* LibHandle::MappableMMap(void* addr, size_t length, off_t offset) const {
382   if (!mappable) mappable = GetMappable();
383   if (!mappable) return MAP_FAILED;
384   void* mapped = mappable->mmap(addr, length, PROT_READ, MAP_PRIVATE, offset);
385   return mapped;
386 }
387 
MappableMUnmap(void * addr,size_t length) const388 void LibHandle::MappableMUnmap(void* addr, size_t length) const {
389   if (mappable) mappable->munmap(addr, length);
390 }
391 
392 /**
393  * SystemElf
394  */
Load(const char * path,int flags)395 already_AddRefed<LibHandle> SystemElf::Load(const char* path, int flags) {
396   /* The Android linker returns a handle when the file name matches an
397    * already loaded library, even when the full path doesn't exist */
398   if (path && path[0] == '/' && (access(path, F_OK) == -1)) {
399     DEBUG_LOG("dlopen(\"%s\", 0x%x) = %p", path, flags, (void*)nullptr);
400     ElfLoader::Singleton.lastError = "Specified file does not exist";
401     return nullptr;
402   }
403 
404   ElfLoader::Singleton.lastError = nullptr;  // Use system dlerror.
405   void* handle = dlopen(path, flags);
406   DEBUG_LOG("dlopen(\"%s\", 0x%x) = %p", path, flags, handle);
407   if (handle) {
408     SystemElf* elf = new SystemElf(path, handle);
409     ElfLoader::Singleton.Register(elf);
410     RefPtr<LibHandle> lib(elf);
411     return lib.forget();
412   }
413   return nullptr;
414 }
415 
~SystemElf()416 SystemElf::~SystemElf() {
417   if (!dlhandle) return;
418   DEBUG_LOG("dlclose(%p [\"%s\"])", dlhandle, GetPath());
419   ElfLoader::Singleton.lastError = nullptr;  // Use system dlerror.
420   dlclose(dlhandle);
421   ElfLoader::Singleton.Forget(this);
422 }
423 
GetSymbolPtr(const char * symbol) const424 void* SystemElf::GetSymbolPtr(const char* symbol) const {
425   ElfLoader::Singleton.lastError = nullptr;  // Use system dlerror.
426   void* sym = dlsym(dlhandle, symbol);
427   DEBUG_LOG("dlsym(%p [\"%s\"], \"%s\") = %p", dlhandle, GetPath(), symbol,
428             sym);
429   return sym;
430 }
431 
GetMappable() const432 Mappable* SystemElf::GetMappable() const {
433   const char* path = GetPath();
434   if (!path) return nullptr;
435 #ifdef ANDROID
436   /* On Android, if we don't have the full path, try in /system/lib */
437   const char* name = LeafName(path);
438   std::string systemPath;
439   if (name == path) {
440     systemPath = "/system/lib/";
441     systemPath += path;
442     path = systemPath.c_str();
443   }
444 #endif
445 
446   return MappableFile::Create(path);
447 }
448 
449 #ifdef __ARM_EABI__
FindExidx(int * pcount) const450 const void* SystemElf::FindExidx(int* pcount) const {
451   /* TODO: properly implement when ElfLoader::GetHandleByPtr
452      does return SystemElf handles */
453   *pcount = 0;
454   return nullptr;
455 }
456 #endif
457 
458 /**
459  * ElfLoader
460  */
461 
462 /* Unique ElfLoader instance */
463 ElfLoader ElfLoader::Singleton;
464 
Load(const char * path,int flags,LibHandle * parent)465 already_AddRefed<LibHandle> ElfLoader::Load(const char* path, int flags,
466                                             LibHandle* parent) {
467   /* Ensure logging is initialized or refresh if environment changed. */
468   Logging::Init();
469 
470   /* Ensure self_elf initialization. */
471   if (!self_elf) Init();
472 
473   RefPtr<LibHandle> handle;
474 
475   /* Handle dlopen(nullptr) directly. */
476   if (!path) {
477     handle = SystemElf::Load(nullptr, flags);
478     return handle.forget();
479   }
480 
481   /* TODO: Handle relative paths correctly */
482   const char* name = LeafName(path);
483 
484   /* Search the list of handles we already have for a match. When the given
485    * path is not absolute, compare file names, otherwise compare full paths. */
486   if (name == path) {
487     AutoLock lock(&handlesMutex);
488     for (LibHandleList::iterator it = handles.begin(); it < handles.end(); ++it)
489       if ((*it)->GetName() && (strcmp((*it)->GetName(), name) == 0)) {
490         handle = *it;
491         return handle.forget();
492       }
493   } else {
494     AutoLock lock(&handlesMutex);
495     for (LibHandleList::iterator it = handles.begin(); it < handles.end(); ++it)
496       if ((*it)->GetPath() && (strcmp((*it)->GetPath(), path) == 0)) {
497         handle = *it;
498         return handle.forget();
499       }
500   }
501 
502   char* abs_path = nullptr;
503   const char* requested_path = path;
504 
505   /* When the path is not absolute and the library is being loaded for
506    * another, first try to load the library from the directory containing
507    * that parent library. */
508   if ((name == path) && parent) {
509     const char* parentPath = parent->GetPath();
510     abs_path = new char[strlen(parentPath) + strlen(path)];
511     strcpy(abs_path, parentPath);
512     char* slash = strrchr(abs_path, '/');
513     strcpy(slash + 1, path);
514     path = abs_path;
515   }
516 
517   Mappable* mappable = GetMappableFromPath(path);
518 
519   /* Try loading with the custom linker if we have a Mappable */
520   if (mappable) handle = CustomElf::Load(mappable, path, flags);
521 
522   /* Try loading with the system linker if everything above failed */
523   if (!handle) handle = SystemElf::Load(path, flags);
524 
525   /* If we didn't have an absolute path and haven't been able to load
526    * a library yet, try in the system search path */
527   if (!handle && abs_path) handle = SystemElf::Load(name, flags);
528 
529   delete[] abs_path;
530   DEBUG_LOG("ElfLoader::Load(\"%s\", 0x%x, %p [\"%s\"]) = %p", requested_path,
531             flags, reinterpret_cast<void*>(parent),
532             parent ? parent->GetPath() : "", static_cast<void*>(handle));
533 
534   return handle.forget();
535 }
536 
GetHandleByPtr(void * addr)537 already_AddRefed<LibHandle> ElfLoader::GetHandleByPtr(void* addr) {
538   AutoLock lock(&handlesMutex);
539   /* Scan the list of handles we already have for a match */
540   for (LibHandleList::iterator it = handles.begin(); it < handles.end(); ++it) {
541     if ((*it)->Contains(addr)) {
542       RefPtr<LibHandle> lib = *it;
543       return lib.forget();
544     }
545   }
546   return nullptr;
547 }
548 
GetMappableFromPath(const char * path)549 Mappable* ElfLoader::GetMappableFromPath(const char* path) {
550   const char* name = LeafName(path);
551   Mappable* mappable = nullptr;
552   RefPtr<Zip> zip;
553   const char* subpath;
554   if ((subpath = strchr(path, '!'))) {
555     char* zip_path = strndup(path, subpath - path);
556     while (*(++subpath) == '/') {
557     }
558     zip = ZipCollection::GetZip(zip_path);
559     free(zip_path);
560     Zip::Stream s;
561     if (zip && zip->GetStream(subpath, &s)) {
562       /* When the MOZ_LINKER_EXTRACT environment variable is set to "1",
563        * compressed libraries are going to be (temporarily) extracted as
564        * files, in the directory pointed by the MOZ_LINKER_CACHE
565        * environment variable. */
566       const char* extract = getenv("MOZ_LINKER_EXTRACT");
567       if (extract && !strncmp(extract, "1", 2 /* Including '\0' */))
568         mappable = MappableExtractFile::Create(name, zip, &s);
569       if (!mappable) {
570         if (s.GetType() == Zip::Stream::DEFLATE) {
571           mappable = MappableDeflate::Create(name, zip, &s);
572         }
573       }
574     }
575   }
576   /* If we couldn't load above, try with a MappableFile */
577   if (!mappable && !zip) mappable = MappableFile::Create(path);
578 
579   return mappable;
580 }
581 
Register(LibHandle * handle)582 void ElfLoader::Register(LibHandle* handle) {
583   AutoLock lock(&handlesMutex);
584   handles.push_back(handle);
585 }
586 
Register(CustomElf * handle)587 void ElfLoader::Register(CustomElf* handle) {
588   Register(static_cast<LibHandle*>(handle));
589   if (dbg) {
590     // We could race with the system linker when modifying the debug map, so
591     // only do so while holding the system linker's internal lock.
592     RunWithSystemLinkerLock([this, handle] { dbg.Add(handle); });
593   }
594 }
595 
Forget(LibHandle * handle)596 void ElfLoader::Forget(LibHandle* handle) {
597   /* Ensure logging is initialized or refresh if environment changed. */
598   Logging::Init();
599 
600   AutoLock lock(&handlesMutex);
601   LibHandleList::iterator it =
602       std::find(handles.begin(), handles.end(), handle);
603   if (it != handles.end()) {
604     DEBUG_LOG("ElfLoader::Forget(%p [\"%s\"])", reinterpret_cast<void*>(handle),
605               handle->GetPath());
606     handles.erase(it);
607   } else {
608     DEBUG_LOG("ElfLoader::Forget(%p [\"%s\"]): Handle not found",
609               reinterpret_cast<void*>(handle), handle->GetPath());
610   }
611 }
612 
Forget(CustomElf * handle)613 void ElfLoader::Forget(CustomElf* handle) {
614   Forget(static_cast<LibHandle*>(handle));
615   if (dbg) {
616     // We could race with the system linker when modifying the debug map, so
617     // only do so while holding the system linker's internal lock.
618     RunWithSystemLinkerLock([this, handle] { dbg.Remove(handle); });
619   }
620 }
621 
Init()622 void ElfLoader::Init() {
623   Dl_info info;
624   /* On Android < 4.1 can't reenter dl* functions. So when the library
625    * containing this code is dlopen()ed, it can't call dladdr from a
626    * static initializer. */
627   if (dladdr(_DYNAMIC, &info) != 0) {
628     self_elf = LoadedElf::Create(info.dli_fname, info.dli_fbase);
629   }
630 #if defined(ANDROID)
631   // On Android < 5.0, resolving weak symbols via dlsym doesn't work.
632   // The weak symbols Gecko uses are in either libc or libm, so we
633   // wrap those such that this linker does symbol resolution for them.
634   if (GetAndroidSDKVersion() < 21) {
635     if (dladdr(FunctionPtr(syscall), &info) != 0) {
636       libc = LoadedElf::Create(info.dli_fname, info.dli_fbase);
637     }
638     if (dladdr(FunctionPtr<int (*)(double)>(isnan), &info) != 0) {
639       libm = LoadedElf::Create(info.dli_fname, info.dli_fbase);
640     }
641   }
642 #endif
643 }
644 
~ElfLoader()645 ElfLoader::~ElfLoader() {
646   LibHandleList list;
647 
648   if (!Singleton.IsShutdownExpected()) {
649     MOZ_CRASH("Unexpected shutdown");
650   }
651 
652   /* Release self_elf and libc */
653   self_elf = nullptr;
654 #if defined(ANDROID)
655   libc = nullptr;
656   libm = nullptr;
657 #endif
658 
659   AutoLock lock(&handlesMutex);
660   /* Build up a list of all library handles with direct (external) references.
661    * We actually skip system library handles because we want to keep at least
662    * some of these open. Most notably, Mozilla codebase keeps a few libgnome
663    * libraries deliberately open because of the mess that libORBit destruction
664    * is. dlclose()ing these libraries actually leads to problems. */
665   for (LibHandleList::reverse_iterator it = handles.rbegin();
666        it < handles.rend(); ++it) {
667     if ((*it)->DirectRefCount()) {
668       if (SystemElf* se = (*it)->AsSystemElf()) {
669         se->Forget();
670       } else {
671         list.push_back(*it);
672       }
673     }
674   }
675   /* Force release all external references to the handles collected above */
676   for (LibHandleList::iterator it = list.begin(); it < list.end(); ++it) {
677     while ((*it)->ReleaseDirectRef()) {
678     }
679   }
680   /* Remove the remaining system handles. */
681   if (handles.size()) {
682     list = handles;
683     for (LibHandleList::reverse_iterator it = list.rbegin(); it < list.rend();
684          ++it) {
685       if ((*it)->AsSystemElf()) {
686         DEBUG_LOG(
687             "ElfLoader::~ElfLoader(): Remaining handle for \"%s\" "
688             "[%" PRIdPTR " direct refs, %" PRIdPTR " refs total]",
689             (*it)->GetPath(), (*it)->DirectRefCount(), (*it)->refCount());
690       } else {
691         DEBUG_LOG(
692             "ElfLoader::~ElfLoader(): Unexpected remaining handle for \"%s\" "
693             "[%" PRIdPTR " direct refs, %" PRIdPTR " refs total]",
694             (*it)->GetPath(), (*it)->DirectRefCount(), (*it)->refCount());
695         /* Not removing, since it could have references to other libraries,
696          * destroying them as a side effect, and possibly leaving dangling
697          * pointers in the handle list we're scanning */
698       }
699     }
700   }
701   pthread_mutex_destroy(&handlesMutex);
702 }
703 
704 #ifdef __ARM_EABI__
__wrap_aeabi_atexit(void * that,ElfLoader::Destructor destructor,void * dso_handle)705 int ElfLoader::__wrap_aeabi_atexit(void* that, ElfLoader::Destructor destructor,
706                                    void* dso_handle) {
707   Singleton.destructors.push_back(
708       DestructorCaller(destructor, that, dso_handle));
709   return 0;
710 }
711 #else
__wrap_cxa_atexit(ElfLoader::Destructor destructor,void * that,void * dso_handle)712 int ElfLoader::__wrap_cxa_atexit(ElfLoader::Destructor destructor, void* that,
713                                  void* dso_handle) {
714   Singleton.destructors.push_back(
715       DestructorCaller(destructor, that, dso_handle));
716   return 0;
717 }
718 #endif
719 
__wrap_cxa_finalize(void * dso_handle)720 void ElfLoader::__wrap_cxa_finalize(void* dso_handle) {
721   /* Call all destructors for the given DSO handle in reverse order they were
722    * registered. */
723   std::vector<DestructorCaller>::reverse_iterator it;
724   for (it = Singleton.destructors.rbegin(); it < Singleton.destructors.rend();
725        ++it) {
726     if (it->IsForHandle(dso_handle)) {
727       it->Call();
728     }
729   }
730 }
731 
Call()732 void ElfLoader::DestructorCaller::Call() {
733   if (destructor) {
734     DEBUG_LOG("ElfLoader::DestructorCaller::Call(%p, %p, %p)",
735               FunctionPtr(destructor), object, dso_handle);
736     destructor(object);
737     destructor = nullptr;
738   }
739 }
740 
DebuggerHelper()741 ElfLoader::DebuggerHelper::DebuggerHelper()
742     : dbg(nullptr), firstAdded(nullptr) {
743   /* Find ELF auxiliary vectors.
744    *
745    * The kernel stores the following data on the stack when starting a
746    * program:
747    *   argc
748    *   argv[0] (pointer into argv strings defined below)
749    *   argv[1] (likewise)
750    *   ...
751    *   argv[argc - 1] (likewise)
752    *   nullptr
753    *   envp[0] (pointer into environment strings defined below)
754    *   envp[1] (likewise)
755    *   ...
756    *   envp[n] (likewise)
757    *   nullptr
758    *   ... (more NULLs on some platforms such as Android 4.3)
759    *   auxv[0] (first ELF auxiliary vector)
760    *   auxv[1] (second ELF auxiliary vector)
761    *   ...
762    *   auxv[p] (last ELF auxiliary vector)
763    *   (AT_NULL, nullptr)
764    *   padding
765    *   argv strings, separated with '\0'
766    *   environment strings, separated with '\0'
767    *   nullptr
768    *
769    * What we are after are the auxv values defined by the following struct.
770    */
771   struct AuxVector {
772     Elf::Addr type;
773     Elf::Addr value;
774   };
775 
776   /* Pointer to the environment variables list */
777   extern char** environ;
778 
779   /* The environment may have changed since the program started, in which
780    * case the environ variables list isn't the list the kernel put on stack
781    * anymore. But in this new list, variables that didn't change still point
782    * to the strings the kernel put on stack. It is quite unlikely that two
783    * modified environment variables point to two consecutive strings in memory,
784    * so we assume that if two consecutive environment variables point to two
785    * consecutive strings, we found strings the kernel put on stack. */
786   char** env;
787   for (env = environ; *env; env++)
788     if (*env + strlen(*env) + 1 == env[1]) break;
789   if (!*env) return;
790 
791   /* Next, we scan the stack backwards to find a pointer to one of those
792    * strings we found above, which will give us the location of the original
793    * envp list. As we are looking for pointers, we need to look at 32-bits or
794    * 64-bits aligned values, depening on the architecture. */
795   char** scan = reinterpret_cast<char**>(reinterpret_cast<uintptr_t>(*env) &
796                                          ~(sizeof(void*) - 1));
797   while (*env != *scan) scan--;
798 
799   /* Finally, scan forward to find the last environment variable pointer and
800    * thus the first auxiliary vector. */
801   while (*scan++)
802     ;
803 
804   /* Some platforms have more NULLs here, so skip them if we encounter them */
805   while (!*scan) scan++;
806 
807   AuxVector* auxv = reinterpret_cast<AuxVector*>(scan);
808 
809   /* The two values of interest in the auxiliary vectors are AT_PHDR and
810    * AT_PHNUM, which gives us the the location and size of the ELF program
811    * headers. */
812   Array<Elf::Phdr> phdrs;
813   char* base = nullptr;
814   while (auxv->type) {
815     if (auxv->type == AT_PHDR) {
816       phdrs.Init(reinterpret_cast<Elf::Phdr*>(auxv->value));
817       /* Assume the base address is the first byte of the same page */
818       base = reinterpret_cast<char*>(PageAlignedPtr(auxv->value));
819     }
820     if (auxv->type == AT_PHNUM) phdrs.Init(auxv->value);
821     auxv++;
822   }
823 
824   if (!phdrs) {
825     DEBUG_LOG("Couldn't find program headers");
826     return;
827   }
828 
829   /* In some cases, the address for the program headers we get from the
830    * auxiliary vectors is not mapped, because of the PT_LOAD segments
831    * definitions in the program executable. Trying to map anonymous memory
832    * with a hint giving the base address will return a different address
833    * if something is mapped there, and the base address otherwise. */
834   MappedPtr mem(MemoryRange::mmap(base, PageSize(), PROT_NONE,
835                                   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
836   if (mem == base) {
837     /* If program headers aren't mapped, try to map them */
838     int fd = open("/proc/self/exe", O_RDONLY);
839     if (fd == -1) {
840       DEBUG_LOG("Failed to open /proc/self/exe");
841       return;
842     }
843     mem.Assign(
844         MemoryRange::mmap(base, PageSize(), PROT_READ, MAP_PRIVATE, fd, 0));
845     /* If we don't manage to map at the right address, just give up. */
846     if (mem != base) {
847       DEBUG_LOG("Couldn't read program headers");
848       return;
849     }
850   }
851   /* Sanity check: the first bytes at the base address should be an ELF
852    * header. */
853   if (!Elf::Ehdr::validate(base)) {
854     DEBUG_LOG("Couldn't find program base");
855     return;
856   }
857 
858   /* Search for the program PT_DYNAMIC segment */
859   Array<Elf::Dyn> dyns;
860   for (Array<Elf::Phdr>::iterator phdr = phdrs.begin(); phdr < phdrs.end();
861        ++phdr) {
862     /* While the program headers are expected within the first mapped page of
863      * the program executable, the executable PT_LOADs may actually make them
864      * loaded at an address that is not the wanted base address of the
865      * library. We thus need to adjust the base address, compensating for the
866      * virtual address of the PT_LOAD segment corresponding to offset 0. */
867     if (phdr->p_type == PT_LOAD && phdr->p_offset == 0) base -= phdr->p_vaddr;
868     if (phdr->p_type == PT_DYNAMIC)
869       dyns.Init(base + phdr->p_vaddr, phdr->p_filesz);
870   }
871   if (!dyns) {
872     DEBUG_LOG("Failed to find PT_DYNAMIC section in program");
873     return;
874   }
875 
876   /* Search for the DT_DEBUG information */
877   for (Array<Elf::Dyn>::iterator dyn = dyns.begin(); dyn < dyns.end(); ++dyn) {
878     if (dyn->d_tag == DT_DEBUG) {
879       dbg = reinterpret_cast<r_debug*>(dyn->d_un.d_ptr);
880       break;
881     }
882   }
883   DEBUG_LOG("DT_DEBUG points at %p", static_cast<void*>(dbg));
884 }
885 
886 /**
887  * Helper class to ensure the given pointer is writable within the scope of
888  * an instance. Permissions to the memory page where the pointer lies are
889  * restored to their original value when the instance is destroyed.
890  */
891 class EnsureWritable {
892  public:
893   template <typename T>
EnsureWritable(T * ptr,size_t length_=sizeof (T))894   explicit EnsureWritable(T* ptr, size_t length_ = sizeof(T)) {
895     MOZ_ASSERT(length_ < PageSize());
896     prot = -1;
897     page = MAP_FAILED;
898 
899     char* firstPage = PageAlignedPtr(reinterpret_cast<char*>(ptr));
900     char* lastPageEnd =
901         PageAlignedEndPtr(reinterpret_cast<char*>(ptr) + length_);
902     length = lastPageEnd - firstPage;
903     uintptr_t start = reinterpret_cast<uintptr_t>(firstPage);
904     uintptr_t end;
905 
906     prot = getProt(start, &end);
907     if (prot == -1 || (start + length) > end) MOZ_CRASH();
908 
909     if (prot & PROT_WRITE) {
910       success = true;
911       return;
912     }
913 
914     page = firstPage;
915     int ret = mprotect(page, length, prot | PROT_WRITE);
916     success = ret == 0;
917     if (!success) {
918       ERROR("mprotect(%p, %zu, %d) = %d (errno=%d; %s)", page, length,
919             prot | PROT_WRITE, ret, errno, strerror(errno));
920     }
921   }
922 
IsWritable() const923   bool IsWritable() const { return success; }
924 
~EnsureWritable()925   ~EnsureWritable() {
926     if (success && page != MAP_FAILED) {
927       mprotect(page, length, prot);
928     }
929   }
930 
931  private:
getProt(uintptr_t addr,uintptr_t * end)932   int getProt(uintptr_t addr, uintptr_t* end) {
933     /* The interesting part of the /proc/self/maps format looks like:
934      * startAddr-endAddr rwxp */
935     int result = 0;
936     AutoCloseFILE f(fopen("/proc/self/maps", "r"));
937     while (f) {
938       unsigned long long startAddr, endAddr;
939       char perms[5];
940       if (fscanf(f, "%llx-%llx %4s %*1024[^\n] ", &startAddr, &endAddr,
941                  perms) != 3)
942         return -1;
943       if (addr < startAddr || addr >= endAddr) continue;
944       if (perms[0] == 'r')
945         result |= PROT_READ;
946       else if (perms[0] != '-')
947         return -1;
948       if (perms[1] == 'w')
949         result |= PROT_WRITE;
950       else if (perms[1] != '-')
951         return -1;
952       if (perms[2] == 'x')
953         result |= PROT_EXEC;
954       else if (perms[2] != '-')
955         return -1;
956       *end = endAddr;
957       return result;
958     }
959     return -1;
960   }
961 
962   int prot;
963   void* page;
964   size_t length;
965   bool success;
966 };
967 
968 /**
969  * The system linker maintains a doubly linked list of library it loads
970  * for use by the debugger. Unfortunately, it also uses the list pointers
971  * in a lot of operations and adding our data in the list is likely to
972  * trigger crashes when the linker tries to use data we don't provide or
973  * that fall off the amount data we allocated. Fortunately, the linker only
974  * traverses the list forward and accesses the head of the list from a
975  * private pointer instead of using the value in the r_debug structure.
976  * This means we can safely add members at the beginning of the list.
977  * Unfortunately, gdb checks the coherency of l_prev values, so we have
978  * to adjust the l_prev value for the first element the system linker
979  * knows about. Fortunately, it doesn't use l_prev, and the first element
980  * is not ever going to be released before our elements, since it is the
981  * program executable, so the system linker should not be changing
982  * r_debug::r_map.
983  */
Add(ElfLoader::link_map * map)984 void ElfLoader::DebuggerHelper::Add(ElfLoader::link_map* map) {
985   if (!dbg->r_brk) return;
986 
987   dbg->r_state = r_debug::RT_ADD;
988   dbg->r_brk();
989 
990   if (!firstAdded) {
991     /* When adding a library for the first time, r_map points to data
992      * handled by the system linker, and that data may be read-only */
993     EnsureWritable w(&dbg->r_map->l_prev);
994     if (!w.IsWritable()) {
995       dbg->r_state = r_debug::RT_CONSISTENT;
996       dbg->r_brk();
997       return;
998     }
999 
1000     firstAdded = map;
1001     dbg->r_map->l_prev = map;
1002   } else
1003     dbg->r_map->l_prev = map;
1004 
1005   map->l_prev = nullptr;
1006   map->l_next = dbg->r_map;
1007 
1008   dbg->r_map = map;
1009   dbg->r_state = r_debug::RT_CONSISTENT;
1010   dbg->r_brk();
1011 }
1012 
Remove(ElfLoader::link_map * map)1013 void ElfLoader::DebuggerHelper::Remove(ElfLoader::link_map* map) {
1014   if (!dbg->r_brk) return;
1015 
1016   dbg->r_state = r_debug::RT_DELETE;
1017   dbg->r_brk();
1018 
1019   if (map == firstAdded) {
1020     /* When removing the first added library, its l_next is going to be
1021      * data handled by the system linker, and that data may be read-only */
1022     EnsureWritable w(&map->l_next->l_prev);
1023     if (!w.IsWritable()) {
1024       dbg->r_state = r_debug::RT_CONSISTENT;
1025       dbg->r_brk();
1026       return;
1027     }
1028 
1029     firstAdded = map->l_prev;
1030     map->l_next->l_prev = map->l_prev;
1031   } else if (map->l_next) {
1032     map->l_next->l_prev = map->l_prev;
1033   }
1034 
1035   if (dbg->r_map == map)
1036     dbg->r_map = map->l_next;
1037   else if (map->l_prev) {
1038     map->l_prev->l_next = map->l_next;
1039   }
1040   dbg->r_state = r_debug::RT_CONSISTENT;
1041   dbg->r_brk();
1042 }
1043 
1044 #if defined(ANDROID) && defined(__NR_sigaction)
1045 /* As some system libraries may be calling signal() or sigaction() to
1046  * set a SIGSEGV handler, effectively breaking MappableSeekableZStream,
1047  * or worse, restore our SIGSEGV handler with wrong flags (which using
1048  * signal() will do), we want to hook into the system's sigaction() to
1049  * replace it with our own wrapper instead, so that our handler is never
1050  * replaced. We used to only do that with libraries this linker loads,
1051  * but it turns out at least one system library does call signal() and
1052  * breaks us (libsc-a3xx.so on the Samsung Galaxy S4).
1053  * As libc's signal (bsd_signal/sysv_signal, really) calls sigaction
1054  * under the hood, instead of calling the signal system call directly,
1055  * we only need to hook sigaction. This is true for both bionic and
1056  * glibc.
1057  */
1058 
1059 /* libc's sigaction */
1060 extern "C" int sigaction(int signum, const struct sigaction* act,
1061                          struct sigaction* oldact);
1062 
1063 /* Simple reimplementation of sigaction. This is roughly equivalent
1064  * to the assembly that comes in bionic, but not quite equivalent to
1065  * glibc's implementation, so we only use this on Android. */
sys_sigaction(int signum,const struct sigaction * act,struct sigaction * oldact)1066 int sys_sigaction(int signum, const struct sigaction* act,
1067                   struct sigaction* oldact) {
1068   return syscall(__NR_sigaction, signum, act, oldact);
1069 }
1070 
1071 /* Replace the first instructions of the given function with a jump
1072  * to the given new function. */
1073 template <typename T>
Divert(T func,T new_func)1074 static bool Divert(T func, T new_func) {
1075   void* ptr = FunctionPtr(func);
1076   uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
1077 
1078 #  if defined(__i386__)
1079   // A 32-bit jump is a 5 bytes instruction.
1080   EnsureWritable w(ptr, 5);
1081   *reinterpret_cast<unsigned char*>(addr) = 0xe9;  // jmp
1082   *reinterpret_cast<intptr_t*>(addr + 1) =
1083       reinterpret_cast<uintptr_t>(new_func) - addr - 5;  // target displacement
1084   return true;
1085 #  elif defined(__arm__) || defined(__aarch64__)
1086   const unsigned char trampoline[] = {
1087 #    ifdef __arm__
1088       // .thumb
1089       0x46, 0x04,              // nop
1090       0x78, 0x47,              // bx pc
1091       0x46, 0x04,              // nop
1092                                // .arm
1093       0x04, 0xf0, 0x1f, 0xe5,  // ldr pc, [pc, #-4]
1094                                // .word <new_func>
1095 #    else  // __aarch64__
1096       0x50, 0x00,
1097       0x00, 0x58,  // ldr x16, [pc, #8]   ; x16 (aka ip0) is the first
1098       0x00, 0x02,
1099       0x1f, 0xd6,  // br x16              ; intra-procedure-call
1100                    // .word <new_func.lo> ; scratch register.
1101                    // .word <new_func.hi>
1102 #    endif
1103   };
1104   const unsigned char* start;
1105 #    ifdef __arm__
1106   if (addr & 0x01) {
1107     /* Function is thumb, the actual address of the code is without the
1108      * least significant bit. */
1109     addr--;
1110     /* The arm part of the trampoline needs to be 32-bit aligned */
1111     if (addr & 0x02)
1112       start = trampoline;
1113     else
1114       start = trampoline + 2;
1115   } else {
1116     /* Function is arm, we only need the arm part of the trampoline */
1117     start = trampoline + 6;
1118   }
1119 #    else  // __aarch64__
1120   start = trampoline;
1121 #    endif
1122 
1123   size_t len = sizeof(trampoline) - (start - trampoline);
1124   EnsureWritable w(reinterpret_cast<void*>(addr), len + sizeof(void*));
1125   memcpy(reinterpret_cast<void*>(addr), start, len);
1126   *reinterpret_cast<void**>(addr + len) = FunctionPtr(new_func);
1127   __builtin___clear_cache(reinterpret_cast<char*>(addr),
1128                           reinterpret_cast<char*>(addr + len + sizeof(void*)));
1129   return true;
1130 #  else
1131   return false;
1132 #  endif
1133 }
1134 #else
1135 #  define sys_sigaction sigaction
1136 template <typename T>
Divert(T func,T new_func)1137 static bool Divert(T func, T new_func) {
1138   return false;
1139 }
1140 #endif
1141 
1142 namespace {
1143 
1144 /* Clock that only accounts for time spent in the current process. */
ProcessTimeStamp_Now()1145 static uint64_t ProcessTimeStamp_Now() {
1146   struct timespec ts;
1147   int rv = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
1148 
1149   if (rv != 0) {
1150     return 0;
1151   }
1152 
1153   uint64_t baseNs = (uint64_t)ts.tv_sec * 1000000000;
1154   return baseNs + (uint64_t)ts.tv_nsec;
1155 }
1156 
1157 }  // namespace
1158 
1159 /* Data structure used to pass data to the temporary signal handler,
1160  * as well as triggering a test crash. */
1161 struct TmpData {
1162   volatile int crash_int;
1163   volatile uint64_t crash_timestamp;
1164 };
1165 
SEGVHandler()1166 SEGVHandler::SEGVHandler()
1167     : initialized(false),
1168       registeredHandler(false),
1169       signalHandlingBroken(true),
1170       signalHandlingSlow(true) {
1171   /* Ensure logging is initialized before the DEBUG_LOG in the test_handler.
1172    * As this constructor runs before the ElfLoader constructor (by effect
1173    * of ElfLoader inheriting from this class), this also initializes on behalf
1174    * of ElfLoader and DebuggerHelper. */
1175   Logging::Init();
1176 
1177   /* Initialize oldStack.ss_flags to an invalid value when used to set
1178    * an alternative stack, meaning we haven't got information about the
1179    * original alternative stack and thus don't mean to restore it in
1180    * the destructor. */
1181   oldStack.ss_flags = SS_ONSTACK;
1182 
1183   /* Get the current segfault signal handler. */
1184   struct sigaction old_action;
1185   sys_sigaction(SIGSEGV, nullptr, &old_action);
1186 
1187   /* Some devices don't provide useful information to their SIGSEGV handlers,
1188    * making it impossible for on-demand decompression to work. To check if
1189    * we're on such a device, setup a temporary handler and deliberately
1190    * trigger a segfault. The handler will set signalHandlingBroken if the
1191    * provided information is bogus.
1192    * Some other devices have a kernel option enabled that makes SIGSEGV handler
1193    * have an overhead so high that it affects how on-demand decompression
1194    * performs. The handler will also set signalHandlingSlow if the triggered
1195    * SIGSEGV took too much time. */
1196   struct sigaction action;
1197   action.sa_sigaction = &SEGVHandler::test_handler;
1198   sigemptyset(&action.sa_mask);
1199   action.sa_flags = SA_SIGINFO | SA_NODEFER;
1200   action.sa_restorer = nullptr;
1201   stackPtr.Assign(MemoryRange::mmap(nullptr, PageSize(), PROT_READ | PROT_WRITE,
1202                                     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
1203   if (stackPtr.get() == MAP_FAILED) return;
1204   if (sys_sigaction(SIGSEGV, &action, nullptr)) return;
1205 
1206   TmpData* data = reinterpret_cast<TmpData*>(stackPtr.get());
1207   data->crash_timestamp = ProcessTimeStamp_Now();
1208   mprotect(stackPtr, stackPtr.GetLength(), PROT_NONE);
1209   data->crash_int = 123;
1210   /* Restore the original segfault signal handler. */
1211   sys_sigaction(SIGSEGV, &old_action, nullptr);
1212   stackPtr.Assign(MAP_FAILED, 0);
1213 }
1214 
FinishInitialization()1215 void SEGVHandler::FinishInitialization() {
1216   /* Ideally, we'd need some locking here, but in practice, we're not
1217    * going to race with another thread. */
1218   initialized = true;
1219 
1220   if (signalHandlingBroken || signalHandlingSlow) return;
1221 
1222   typedef int (*sigaction_func)(int, const struct sigaction*,
1223                                 struct sigaction*);
1224 
1225   sigaction_func libc_sigaction;
1226 
1227 #if defined(ANDROID)
1228   /* Android > 4.4 comes with a sigaction wrapper in a LD_PRELOADed library
1229    * (libsigchain) for ART. That wrapper kind of does the same trick as we
1230    * do, so we need extra care in handling it.
1231    * - Divert the libc's sigaction, assuming the LD_PRELOADed library uses
1232    *   it under the hood (which is more or less true according to the source
1233    *   of that library, since it's doing a lookup in RTLD_NEXT)
1234    * - With the LD_PRELOADed library in place, all calls to sigaction from
1235    *   from system libraries will go to the LD_PRELOADed library.
1236    * - The LD_PRELOADed library calls to sigaction go to our __wrap_sigaction.
1237    * - The calls to sigaction from libraries faulty.lib loads are sent to
1238    *   the LD_PRELOADed library.
1239    * In practice, for signal handling, this means:
1240    * - The signal handler registered to the kernel is ours.
1241    * - Our handler redispatches to the LD_PRELOADed library's if there's a
1242    *   segfault we don't handle.
1243    * - The LD_PRELOADed library redispatches according to whatever system
1244    *   library or faulty.lib-loaded library set with sigaction.
1245    *
1246    * When there is no sigaction wrapper in place:
1247    * - Divert the libc's sigaction.
1248    * - Calls to sigaction from system library and faulty.lib-loaded libraries
1249    *   all go to the libc's sigaction, which end up in our __wrap_sigaction.
1250    * - The signal handler registered to the kernel is ours.
1251    * - Our handler redispatches according to whatever system library or
1252    *   faulty.lib-loaded library set with sigaction.
1253    */
1254   void* libc = dlopen("libc.so", RTLD_GLOBAL | RTLD_LAZY);
1255   if (libc) {
1256     /*
1257      * Lollipop bionic only has a small trampoline in sigaction, with the real
1258      * work happening in __sigaction. Divert there instead of sigaction if it
1259      * exists. Bug 1154803
1260      */
1261     libc_sigaction =
1262         reinterpret_cast<sigaction_func>(dlsym(libc, "__sigaction"));
1263 
1264     if (!libc_sigaction) {
1265       libc_sigaction =
1266           reinterpret_cast<sigaction_func>(dlsym(libc, "sigaction"));
1267     }
1268   } else
1269 #endif
1270   {
1271     libc_sigaction = sigaction;
1272   }
1273 
1274   if (!Divert(libc_sigaction, __wrap_sigaction)) return;
1275 
1276   /* Setup an alternative stack if the already existing one is not big
1277    * enough, or if there is none. */
1278   if (sigaltstack(nullptr, &oldStack) == 0) {
1279     if (oldStack.ss_flags == SS_ONSTACK) oldStack.ss_flags = 0;
1280     if (!oldStack.ss_sp || oldStack.ss_size < stackSize) {
1281       stackPtr.Assign(MemoryRange::mmap(nullptr, stackSize,
1282                                         PROT_READ | PROT_WRITE,
1283                                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
1284       if (stackPtr.get() == MAP_FAILED) return;
1285       stack_t stack;
1286       stack.ss_sp = stackPtr;
1287       stack.ss_size = stackSize;
1288       stack.ss_flags = 0;
1289       if (sigaltstack(&stack, nullptr) != 0) return;
1290     }
1291   }
1292   /* Register our own handler, and store the already registered one in
1293    * SEGVHandler's struct sigaction member */
1294   action.sa_sigaction = &SEGVHandler::handler;
1295   action.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
1296   registeredHandler = !sys_sigaction(SIGSEGV, &action, &this->action);
1297 }
1298 
~SEGVHandler()1299 SEGVHandler::~SEGVHandler() {
1300   /* Restore alternative stack for signals */
1301   if (oldStack.ss_flags != SS_ONSTACK) sigaltstack(&oldStack, nullptr);
1302   /* Restore original signal handler */
1303   if (registeredHandler) sys_sigaction(SIGSEGV, &this->action, nullptr);
1304 }
1305 
1306 /* Test handler for a deliberately triggered SIGSEGV that determines whether
1307  * useful information is provided to signal handlers, particularly whether
1308  * si_addr is filled in properly, and whether the segfault handler is called
1309  * quickly enough. */
test_handler(int signum,siginfo_t * info,void * context)1310 void SEGVHandler::test_handler(int signum, siginfo_t* info, void* context) {
1311   SEGVHandler& that = ElfLoader::Singleton;
1312   if (signum == SIGSEGV && info && info->si_addr == that.stackPtr.get())
1313     that.signalHandlingBroken = false;
1314   mprotect(that.stackPtr, that.stackPtr.GetLength(), PROT_READ | PROT_WRITE);
1315   TmpData* data = reinterpret_cast<TmpData*>(that.stackPtr.get());
1316   uint64_t latency = ProcessTimeStamp_Now() - data->crash_timestamp;
1317   DEBUG_LOG("SEGVHandler latency: %" PRIu64, latency);
1318   /* See bug 886736 for timings on different devices, 150 µs is reasonably above
1319    * the latency on "working" devices and seems to be short enough to not incur
1320    * a huge overhead to on-demand decompression. */
1321   if (latency <= 150000) that.signalHandlingSlow = false;
1322 }
1323 
1324 /* TODO: "properly" handle signal masks and flags */
handler(int signum,siginfo_t * info,void * context)1325 void SEGVHandler::handler(int signum, siginfo_t* info, void* context) {
1326   // ASSERT(signum == SIGSEGV);
1327   DEBUG_LOG("Caught segmentation fault @%p", info->si_addr);
1328 
1329   /* Redispatch to the registered handler */
1330   SEGVHandler& that = ElfLoader::Singleton;
1331   if (that.action.sa_flags & SA_SIGINFO) {
1332     DEBUG_LOG("Redispatching to registered handler @%p",
1333               FunctionPtr(that.action.sa_sigaction));
1334     that.action.sa_sigaction(signum, info, context);
1335   } else if (that.action.sa_handler == SIG_DFL) {
1336     DEBUG_LOG("Redispatching to default handler");
1337     /* Reset the handler to the default one, and trigger it. */
1338     sys_sigaction(signum, &that.action, nullptr);
1339     raise(signum);
1340   } else if (that.action.sa_handler != SIG_IGN) {
1341     DEBUG_LOG("Redispatching to registered handler @%p",
1342               FunctionPtr(that.action.sa_handler));
1343     that.action.sa_handler(signum);
1344   } else {
1345     DEBUG_LOG("Ignoring");
1346   }
1347 }
1348 
__wrap_sigaction(int signum,const struct sigaction * act,struct sigaction * oldact)1349 int SEGVHandler::__wrap_sigaction(int signum, const struct sigaction* act,
1350                                   struct sigaction* oldact) {
1351   SEGVHandler& that = ElfLoader::Singleton;
1352 
1353   /* Use system sigaction() function for all but SIGSEGV signals. */
1354   if (!that.registeredHandler || (signum != SIGSEGV))
1355     return sys_sigaction(signum, act, oldact);
1356 
1357   if (oldact) *oldact = that.action;
1358   if (act) that.action = *act;
1359   return 0;
1360 }
1361