tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MmapFaultHandler.h (4274B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef MmapFaultHandler_h_
      7 #define MmapFaultHandler_h_
      8 
      9 #if defined(XP_WIN)
     10 // Windows
     11 
     12 #  ifdef HAVE_SEH_EXCEPTIONS
     13 #    define MMAP_FAULT_HANDLER_BEGIN_HANDLE(fd) __try {
     14 #    define MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, bufLen) __try {
     15 #    define MMAP_FAULT_HANDLER_CATCH(retval)                  \
     16      }                                                       \
     17      __except (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR \
     18                    ? EXCEPTION_EXECUTE_HANDLER               \
     19                    : EXCEPTION_CONTINUE_SEARCH) {            \
     20        NS_WARNING("unexpected EXCEPTION_IN_PAGE_ERROR");     \
     21        return retval;                                        \
     22      }
     23 #  else
     24 #    define MMAP_FAULT_HANDLER_BEGIN_HANDLE(fd) {
     25 #    define MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, bufLen) {
     26 #    define MMAP_FAULT_HANDLER_CATCH(retval) }
     27 #  endif
     28 
     29 #elif defined(XP_DARWIN)
     30 // MacOS
     31 
     32 #  define MMAP_FAULT_HANDLER_BEGIN_HANDLE(fd) {
     33 #  define MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, bufLen) {
     34 #  define MMAP_FAULT_HANDLER_CATCH(retval) }
     35 
     36 #elif defined(__wasi__)
     37 
     38 #  define MMAP_FAULT_HANDLER_BEGIN_HANDLE(fd) {
     39 #  define MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, bufLen) {
     40 #  define MMAP_FAULT_HANDLER_CATCH(retval) }
     41 
     42 #else
     43 // Linux
     44 
     45 #  include "mozilla/Attributes.h"
     46 #  include "mozilla/Types.h"
     47 #  include <stdint.h>
     48 #  include <setjmp.h>
     49 
     50 class MOZ_RAII MmapAccessScope {
     51 public:
     52  MFBT_API MmapAccessScope(void* aBuf, uint32_t aBufLen,
     53                           const char* aFilename = nullptr);
     54  MFBT_API ~MmapAccessScope();
     55 
     56  MmapAccessScope(const MmapAccessScope&) = delete;
     57  MmapAccessScope& operator=(const MmapAccessScope&) = delete;
     58 
     59  void SetThreadLocalScope();
     60  bool IsInsideBuffer(void* aPtr);
     61  void CrashWithInfo(void* aPtr);
     62 
     63  // sigsetjmp cannot be called from a method that returns before calling
     64  // siglongjmp, so the macro must call sigsetjmp directly and mJmpBuf must be
     65  // public.
     66  sigjmp_buf mJmpBuf;
     67 
     68 private:
     69  void* mBuf;
     70  const char* mFilename;
     71  uint32_t mBufLen;
     72  MmapAccessScope* mPreviousScope;
     73 };
     74 
     75 // Gets around warnings for null-checking in a macro.
     76 template <typename T>
     77 inline bool ValidFD(T fd) {
     78  return !!fd;
     79 }
     80 
     81 #  define MMAP_FAULT_HANDLER_BEGIN_HANDLE(fd)                  \
     82    {                                                          \
     83      void* mmapScopeBuf = nullptr;                            \
     84      nsCString mmapScopeFilename;                             \
     85      uint32_t mmapScopeBufLen = 0;                            \
     86      if (ValidFD(fd) && fd->mMap) {                           \
     87        mmapScopeBuf = (void*)fd->mFileStart;                  \
     88        mmapScopeBufLen = fd->mTotalLen;                       \
     89      }                                                        \
     90      if (ValidFD(fd) && fd->mFile) {                          \
     91        nsCOMPtr<nsIFile> file = fd->mFile.GetBaseFile();      \
     92        if (file) {                                            \
     93          file->GetNativeLeafName(mmapScopeFilename);          \
     94        }                                                      \
     95      }                                                        \
     96      MmapAccessScope mmapScope(mmapScopeBuf, mmapScopeBufLen, \
     97                                mmapScopeFilename.get());      \
     98      if (sigsetjmp(mmapScope.mJmpBuf, 0) == 0) {
     99 #  define MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, bufLen)   \
    100    {                                                    \
    101      MmapAccessScope mmapScope((void*)(buf), (bufLen)); \
    102      if (sigsetjmp(mmapScope.mJmpBuf, 0) == 0) {
    103 #  define MMAP_FAULT_HANDLER_CATCH(retval)                       \
    104    }                                                            \
    105    else {                                                       \
    106      NS_WARNING("SIGBUS received when accessing mmapped file"); \
    107      return retval;                                             \
    108    }                                                            \
    109    }
    110 
    111 #endif
    112 
    113 #endif