summaryrefslogtreecommitdiffstats
path: root/browser/app/winlauncher/freestanding/SharedSection.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /browser/app/winlauncher/freestanding/SharedSection.h
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--browser/app/winlauncher/freestanding/SharedSection.h118
1 files changed, 118 insertions, 0 deletions
diff --git a/browser/app/winlauncher/freestanding/SharedSection.h b/browser/app/winlauncher/freestanding/SharedSection.h
new file mode 100644
index 0000000000..0724cfc05d
--- /dev/null
+++ b/browser/app/winlauncher/freestanding/SharedSection.h
@@ -0,0 +1,118 @@
+/* -*- 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/NativeNt.h"
+#include "mozilla/interceptor/MMPolicies.h"
+
+namespace mozilla {
+namespace freestanding {
+
+// 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.
+class MOZ_TRIVIAL_CTOR_DTOR Kernel32ExportsSolver final
+ : public interceptor::MMPolicyInProcessEarlyStage::Kernel32Exports {
+ enum class State {
+ Uninitialized,
+ Initialized,
+ Resolved,
+ } mState;
+
+ static ULONG NTAPI ResolveOnce(PRTL_RUN_ONCE aRunOnce, PVOID aParameter,
+ PVOID*);
+ void ResolveInternal();
+
+ public:
+ Kernel32ExportsSolver() = default;
+
+ Kernel32ExportsSolver(const Kernel32ExportsSolver&) = delete;
+ Kernel32ExportsSolver(Kernel32ExportsSolver&&) = delete;
+ Kernel32ExportsSolver& operator=(const Kernel32ExportsSolver&) = delete;
+ Kernel32ExportsSolver& operator=(Kernel32ExportsSolver&&) = delete;
+
+ bool IsInitialized() const;
+ bool IsResolved() const;
+
+ void Init();
+ void Resolve(RTL_RUN_ONCE& aRunOnce);
+};
+
+// 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) Array of NT paths of the executable's dependent modules
+// Formatted as a null-delimited wide-character string set ending with
+// an empty string.
+//
+// +--------------------------------------------------------------+
+// | (1) | FlushInstructionCache |
+// | | GetModuleHandleW |
+// | | GetSystemInfo |
+// | | VirtualProtect |
+// | | State [Uninitialized|Initialized|Resolved] |
+// +--------------------------------------------------------------+
+// | (2) | L"NT path 1" |
+// | | L"NT path 2" |
+// | | ... |
+// | | L"" |
+// +--------------------------------------------------------------+
+class MOZ_TRIVIAL_CTOR_DTOR SharedSection final {
+ // 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 void* sWriteCopyView;
+
+ static constexpr size_t kSharedViewSize = 0x1000;
+
+ public:
+ struct Layout final {
+ Kernel32ExportsSolver mK32Exports;
+ wchar_t mModulePathArray[1];
+
+ Layout() = delete; // disallow instantiation
+ };
+
+ // Replace |sSectionHandle| with a given handle.
+ static void Reset(HANDLE aNewSecionObject = sSectionHandle);
+
+ // Replace |sSectionHandle| with a new readonly handle.
+ static void ConvertToReadOnly();
+
+ // Create a new writable section and initialize the Kernel32ExportsSolver
+ // part.
+ static LauncherVoidResult Init(const nt::PEHeaders& aPEHeaders);
+
+ // Append a new string to the |sSectionHandle|
+ static LauncherVoidResult AddDepenentModule(PCUNICODE_STRING aNtPath);
+
+ // Map |sSectionHandle| to a copy-on-write page and return its address.
+ static LauncherResult<Layout*> GetView();
+
+ // Transfer |sSectionHandle| to a process associated with |aTransferMgr|.
+ static LauncherVoidResult TransferHandle(
+ nt::CrossExecTransferManager& aTransferMgr, DWORD aDesiredAccess,
+ HANDLE* aDestinationAddress = &sSectionHandle);
+};
+
+extern SharedSection gSharedSection;
+extern RTL_RUN_ONCE gK32ExportsResolveOnce;
+
+} // namespace freestanding
+} // namespace mozilla
+
+#endif // mozilla_freestanding_SharedSection_h