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