Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/browser/app/winlauncher/freestanding/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 9 kB image not shown  

Quelle  SharedSection.h

  Sprache: C
 

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */


#ifndef mozilla_freestanding_SharedSection_h
#define mozilla_freestanding_SharedSection_h

#include "mozilla/DynamicBlocklist.h"
#include "mozilla/glue/SharedSection.h"
#include "mozilla/NativeNt.h"
#include "mozilla/interceptor/MMPolicies.h"

// clang-format off
#define MOZ_LITERAL_UNICODE_STRING(s)                                        \
  {                                                                          \
    /* Length of the string in bytes, less the null terminator */            \
    sizeof(s) - sizeof(wchar_t),                                             \
    /* Length of the string in bytes, including the null terminator */       \
    sizeof(s),                                                               \
    /* Pointer to the buffer */                                              \
    const_cast<wchar_t*>(s)                                                  \
  }
// clang-format on

namespace mozilla {
namespace freestanding {
class SharedSectionTestHelper;

struct DllBlockInfoComparator {
  explicit DllBlockInfoComparator(const UNICODE_STRING& aTarget)
      : mTarget(&aTarget) {}

  int operator()(const DllBlockInfo& aVal) const {
    return static_cast<int>(
        ::RtlCompareUnicodeString(mTarget, &aVal.mName, TRUE));
  }

  PCUNICODE_STRING mTarget;
};

// This class calculates RVAs of kernel32's functions and transfers them
// to a target process, where the transferred RVAs are resolved into
// function addresses so that the target process can use them after
// kernel32.dll is loaded and before IAT is resolved.
struct MOZ_TRIVIAL_CTOR_DTOR Kernel32ExportsSolver final
    : interceptor::MMPolicyInProcessEarlyStage::Kernel32Exports {
  void Init();
  bool Resolve();
};

// This class manages a section which is created in the launcher process and
// mapped in the browser process and the sandboxed processes.  The section's
// layout is represented as SharedSection::Layout.
//
// (1) Kernel32's functions required for MMPolicyInProcessEarlyStage
//     Formatted as Kernel32ExportsSolver.
//
// (2) Various flags and offsets
//
// (3) Entries in the dynamic blocklist, in DllBlockInfo format. There
//     are mNumBlockEntries of these, followed by one that has mName.Length
//     of 0. Note that the strings that contain
//     the names of the entries in the blocklist are stored concatenated
//     after the last entry. The mName pointers in each DllBlockInfo point
//     to these strings correctly in Resolve(), so clients don't need
//     to do anything special to read these strings.
//
// (4) Array of NT paths of the executable's dependent modules
//     Formatted as a null-delimited wide-character string set ending with
//     an empty string. These entries start at offset
//     mDependentModulePathArrayStart (in bytes) from the beginning
//     of the structure
//
// +--------------------------------------------------------------+
// | (1) | FlushInstructionCache                                  |
// |     | GetModuleHandleW                                       |
// |     | GetSystemInfo                                          |
// |     | VirtualProtect                                         |
// |     | State [kUninitialized|kInitialized|kResolved]          |
// +--------------------------------------------------------------+
// | (2) | (flags and offsets)                                    |
// +--------------------------------------------------------------+
// | (3) | <DllBlockInfo for first entry in dynamic blocklist>    |
// |     | <DllBlockInfo for second entry in dynamic blocklist>   |
// |     | ...                                                    |
// |     | <DllBlockInfo for last entry in dynamic blocklist>     |
// |     | <DllBlockInfo with mName.Length of 0>                  |
// |     | L"string1.dllstring2.dll...stringlast.dll"             |
// +--------------------------------------------------------------+
// | (4) | L"NT path 1"                                           |
// |     | L"NT path 2"                                           |
// |     | ...                                                    |
// |     | L""                                                    |
// +--------------------------------------------------------------+
class MOZ_TRIVIAL_CTOR_DTOR SharedSection final : public nt::SharedSection {
  struct Layout final {
    enum class State {
      kUninitialized,
      kInitialized,
      kLoadedDynamicBlocklistEntries,
      kResolved,
    } mState;

    Kernel32ExportsSolver mK32Exports;
    // 1 if the blocklist is disabled, 0 otherwise.
    // If the blocklist is disabled, the entries are still loaded to make it
    // easy for the user to remove any they don't want, but none of the DLLs
    // here are actually blocked.
    // Stored as a uint32_t for alignment reasons.
    uint32_t mBlocklistIsDisabled;
    // The offset, in bytes, from the beginning of the Layout structure to the
    // first dependent module entry.
    // When the Layout object is created, this value is 0, indicating that no
    // dependent modules have been added and it is safe to add DllBlockInfo
    // entries.
    // After this value is set to something non-0, no more DllBlockInfo entries
    // can be added.
    uint32_t mDependentModulePathArrayStart;
    // The number of blocklist entries.
    uint32_t mNumBlockEntries;
    DllBlockInfo mFirstBlockEntry[1];

    Span<DllBlockInfo> GetModulePathArray() {
      return Span<DllBlockInfo>(
          mFirstBlockEntry,
          (kSharedViewSize - (reinterpret_cast<uintptr_t>(mFirstBlockEntry) -
                              reinterpret_cast<uintptr_t>(this))) /
              sizeof(DllBlockInfo));
    }
    // Can be used to make sure we don't step past the end of the shared memory
    // section.
    static constexpr uint32_t GetMaxNumBlockEntries() {
      return (kSharedViewSize - (offsetof(Layout, mFirstBlockEntry))) /
             sizeof(DllBlockInfo);
    }
    Layout() = delete;  // disallow instantiation
    bool Resolve();
    bool IsDisabled() const;
    const DllBlockInfo* SearchBlocklist(const UNICODE_STRING& aLeafName) const;
    Span<wchar_t> GetDependentModules();
  };

  // As we define a global variable of this class and use it in our blocklist
  // which is excuted in a process's early stage.  If we have a complex dtor,
  // the static initializer tries to register that dtor with onexit() of
  // ucrtbase.dll which is not loaded yet, resulting in crash.  Thus, we have
  // a raw handle and a pointer as a static variable and manually release them
  // by calling Reset() where possible.
  static HANDLE sSectionHandle;
  static Layout* sWriteCopyView;
  static RTL_RUN_ONCE sEnsureOnce;

  // The sLock lock guarantees that while it is held, sSectionHandle will not
  // change nor get closed, sEnsureOnce will not get reinitialized, and
  // sWriteCopyView will not change nor get unmapped once initialized. We take
  // sLock on paths that could run concurrently with ConvertToReadOnly(). This
  // method is only called on the main process, and very early, so the only
  // real risk here should be threads started by third-party products reaching
  // our patched_NtMapViewOfSection (see bug 1850969).
  static nt::SRWLock sLock;

  static ULONG NTAPI EnsureWriteCopyViewOnce(PRTL_RUN_ONCE, PVOID, PVOID*);
  static Layout* EnsureWriteCopyView(bool requireKernel32Exports = false);

  static constexpr size_t kSharedViewSize = 0x1000;

  // For test use only
  friend class SharedSectionTestHelper;

 public:
  // Replace |sSectionHandle| with a given handle.
  static void Reset(HANDLE aNewSectionObject = sSectionHandle);

  static inline nt::AutoSharedLock AutoNoReset() {
    return nt::AutoSharedLock{sLock};
  }

  // Replace |sSectionHandle| with a new readonly handle.
  static void ConvertToReadOnly();

  // Create a new writable section and initialize the Kernel32ExportsSolver
  // part.
  static LauncherVoidResult Init();

  // Append a new string to the |sSectionHandle|
  static LauncherVoidResult AddDependentModule(PCUNICODE_STRING aNtPath);
  static LauncherVoidResult SetBlocklist(const DynamicBlockList& aBlocklist,
                                         bool isDisabled);

  // Map |sSectionHandle| to a copy-on-write page and return a writable pointer
  // to each structure, or null if Layout failed to resolve exports.
  Kernel32ExportsSolver* GetKernel32Exports();
  Maybe<Vector<const wchar_t*>> GetDependentModules() final override;
  Span<const DllBlockInfo> GetDynamicBlocklist() final override;

  static bool IsDisabled();
  static const DllBlockInfo* SearchBlocklist(const UNICODE_STRING& aLeafName);

  // Transfer |sSectionHandle| to a process associated with |aTransferMgr|.
  static LauncherVoidResult TransferHandle(
      nt::CrossExecTransferManager& aTransferMgr, DWORD aDesiredAccess,
      HANDLE* aDestinationAddress = &sSectionHandle);
};

extern SharedSection gSharedSection;

}  // namespace freestanding
}  // namespace mozilla

#endif  // mozilla_freestanding_SharedSection_h

Messung V0.5 in Prozent
C=55 H=100 G=80

¤ Dauer der Verarbeitung: 0.33 Sekunden  (vorverarbeitet am  2026-05-05) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.