This patch makes sure the repo can be built without `MOZ_LAUNCHER_PROCESS`.
- Compile WinTokenUtils.cpp under winlaucher regardless of `MOZ_LAUNCHER_PROCESS`
because we still need `IsAdminWithoutUac`.
- Skip TestDllBlocklist.NoOpEntryPoint GTest because the `RedirectToNoOpEntryPoint`
feature is only available with the new blocklist with the launcher process.
Differential Revision: https://phabricator.services.mozilla.com/D108142
A. The shell provides the startup shortcut in STARTUPINFOW when it
starts a process. If the launcher process runs, we must pass this along
to the real process being created.
B. lpTitle can be overwritten, in particular when the AUMID is set for
WinTaskbar, so save it in XREMain::XRE_mainStartup() in order to access
it later.
C. Add an accessor for the saved shortcut.
Differential Revision: https://phabricator.services.mozilla.com/D106343
We used to record a DLL loading event only when a module was loaded.
With this patch, we record an event for a module blocked by our DLL
blocklist as well as a loaded module. It is achieved by calling
to `ModuleLoadFrame::NotifySectionMap` in `patched_NtMapViewOfSection`
regardless of the block action.
This patch introduces a new member `ModuleLoadInfo::mStatus` and
`ProcessedModuleLoadEvent::mLoadStatus` to keep the DLL loading status,
which will be added to the third-party-modules ping by a following patch.
Differential Revision: https://phabricator.services.mozilla.com/D102407
We used to record a DLL loading event only when a module was loaded.
With this patch, we record an event for a module blocked by our DLL
blocklist as well as a loaded module. It is achieved by calling
to `ModuleLoadFrame::NotifySectionMap` in `patched_NtMapViewOfSection`
regardless of the block action.
This patch introduces a new member `ModuleLoadInfo::mStatus` and
`ProcessedModuleLoadEvent::mLoadStatus` to keep the DLL loading status,
which will be added to the third-party-modules ping by a following patch.
Differential Revision: https://phabricator.services.mozilla.com/D102407
This patch is to improve the way to detect an injected dependent module for
automatic DLL blocking (bug 1659438).
In the previous version, we created a list of dependent modules in the launcher
process and shared it with other processes via the shared section. However, it
was not compatible with third-party applications who tamper the Import Table and
revert it in the injected module's DllMain (bug 1682834) because we parsed the
Import Table in the launcher process after it was reverted.
With this patch, we check the Import Table in `patched_NtMapViewOfSection`,
so we can see tampering before it's reverted. More specifically, we create
a list of dependent modules in the browser process as below.
1. The launcher process creates a section object and initializes
the kernel32.dll's functions in it.
2. The launcher process transfers a writable handle of the shared
section to the browser process.
3. In the browser process, if an injected dependent module is being
mapped by `NtMapViewOfSection`, we add its NT path to the shared
section and block it with `REDIRECT_TO_NOOP_ENTRYPOINT`.
4. The `main` function of the browser process converts the writable
handle of the shared section into a readonly handle.
5. The browser process transfers a readonly handle of the shared
section to a sandbox process.
Since automatic DLL blocking may still cause a compat issue like bug 1682304,
we activate it only in Nightly for now.
Differential Revision: https://phabricator.services.mozilla.com/D101460
This patch is to improve the way to detect an injected dependent module for
automatic DLL blocking (bug 1659438).
In the previous version, we created a list of dependent modules in the launcher
process and shared it with other processes via the shared section. However, it
was not compatible with third-party applications who tamper the Import Table and
revert it in the injected module's DllMain (bug 1682834) because we parsed the
Import Table in the launcher process after it was reverted.
With this patch, we check the Import Table in `patched_NtMapViewOfSection`,
so we can see tampering before it's reverted. More specifically, we create
a list of dependent modules in the browser process as below.
1. The launcher process creates a section object and initializes
the kernel32.dll's functions in it.
2. The launcher process transfers a writable handle of the shared
section to the browser process.
3. In the browser process, if an injected dependent module is being
mapped by `NtMapViewOfSection`, we add its NT path to the shared
section and block it with `REDIRECT_TO_NOOP_ENTRYPOINT`.
4. The `main` function of the browser process converts the writable
handle of the shared section into a readonly handle.
5. The browser process transfers a readonly handle of the shared
section to a sandbox process.
Since automatic DLL blocking may still cause a compat issue like bug 1682304,
we activate it only in Nightly for now.
Differential Revision: https://phabricator.services.mozilla.com/D101460
IBM Security Trusteer Rapport does not only inject a module via Import Table
but also apply a window hook. Bug 1682304 revealed blocking their module with
RedirectToNoOpEntryPoint crashes a process because their hook function assumes
injection was succceeded by default.
In non-Nightly, therefore, we enable neither automatic DLL blocking nor pre-spawn CIG.
Differential Revision: https://phabricator.services.mozilla.com/D99966
Bug 1659438 introduced an exported function `GetDependentModulePaths` in firefox.exe
so that our sandboxBroker can easily access the shared section whose handle is owned
by firefox.exe.
This patch disallows `GetDependentModulePaths` to be called from someone other than
xul.dll in order to harden the attack to tamper our shared section. This cannot
prevent all possible attacks, but it's better than nothing.
Differential Revision: https://phabricator.services.mozilla.com/D97377
Our DLL blocklist has an option `REDIRECT_TO_NOOP_ENTRYPOINT`, with which we
redirect a target module's entrypoint to a function just returning `TRUE` so that
it does not have a chance to intereact with our code.
With this patch, we apply the `REDIRECT_TO_NOOP_ENTRYPOINT` method automatically
to a module which is included in the executable's Import Directory Table.
Depends on D96284
Differential Revision: https://phabricator.services.mozilla.com/D96285
This patch adds a list of the executable's dependent module's path to SharedSection
as an array of the offset to a string and a string buffer. A following patch will
use this data from the browser process and the sandboxed processes.
Depends on D96283
Differential Revision: https://phabricator.services.mozilla.com/D96284
We transfer several ntdll's function addresses to a child process directly via
`WriteProcessMemory`. This patch changes the way to transfer data to using
a section object as Chromium sandbox does, so that we can transfer more data
with the same cost as transferring a single handle value.
Depends on D96282
Differential Revision: https://phabricator.services.mozilla.com/D96283
The latest launcher process showed one of the top failures was `WriteProcessMemory` in
`CopyStubToChildProcess` failed with `ERROR_INVALID_ADDRESS` or `ERROR_NOACCESS`, that
is to store a trampoline address to the global variable of firefox.exe failed. Its root
cause should be the same as bug 1662560, the executable was loaded onto a different
address from the browser process.
The fix is to to expand the usage of `CrossExecTransferManager` to `FuncHookCrossProcess`
and `Kernel32ExportsSolver`.
Depends on D94652
Differential Revision: https://phabricator.services.mozilla.com/D94653
This patch introduces a class `CrossExecTransferManager` to manage the data
transfer from the current process to a remote process via `WriteProcessMemory`.
The class also encapsulates a logic to bridge the gap between two executable's
imagebase.
Differential Revision: https://phabricator.services.mozilla.com/D94652
Allow-list all Python code in tree for use with the black linter, and re-format all code in-tree accordingly.
To produce this patch I did all of the following:
1. Make changes to tools/lint/black.yml to remove include: stanza and update list of source extensions.
2. Run ./mach lint --linter black --fix
3. Make some ad-hoc manual updates to python/mozbuild/mozbuild/test/configure/test_configure.py -- it has some hard-coded line numbers that the reformat breaks.
4. Make some ad-hoc manual updates to `testing/marionette/client/setup.py`, `testing/marionette/harness/setup.py`, and `testing/firefox-ui/harness/setup.py`, which have hard-coded regexes that break after the reformat.
5. Add a set of exclusions to black.yml. These will be deleted in a follow-up bug (1672023).
# ignore-this-changeset
Differential Revision: https://phabricator.services.mozilla.com/D94045
Allow-list all Python code in tree for use with the black linter, and re-format all code in-tree accordingly.
To produce this patch I did all of the following:
1. Make changes to tools/lint/black.yml to remove include: stanza and update list of source extensions.
2. Run ./mach lint --linter black --fix
3. Make some ad-hoc manual updates to python/mozbuild/mozbuild/test/configure/test_configure.py -- it has some hard-coded line numbers that the reformat breaks.
4. Make some ad-hoc manual updates to `testing/marionette/client/setup.py`, `testing/marionette/harness/setup.py`, and `testing/firefox-ui/harness/setup.py`, which have hard-coded regexes that break after the reformat.
5. Add a set of exclusions to black.yml. These will be deleted in a follow-up bug (1672023).
# ignore-this-changeset
Differential Revision: https://phabricator.services.mozilla.com/D94045
Allow-list all Python code in tree for use with the black linter, and re-format all code in-tree accordingly.
To produce this patch I did all of the following:
1. Make changes to tools/lint/black.yml to remove include: stanza and update list of source extensions.
2. Run ./mach lint --linter black --fix
3. Make some ad-hoc manual updates to python/mozbuild/mozbuild/test/configure/test_configure.py -- it has some hard-coded line numbers that the reformat breaks.
4. Add a set of exclusions to black.yml. These will be deleted in a follow-up bug (1672023).
# ignore-this-changeset
Differential Revision: https://phabricator.services.mozilla.com/D94045
This is the third attempt to investigate the launcher failure of our detour.
The previous commits d8315e4ed18d and 1b81ea85c43d added the assembly bytes
of a detour target and a special error code `DetourResultCode` to the launcher
failure ping.
In the latest telemetry data, however, the most common value of `hresult`
is still `ERROR_UNIDENTIFIED_ERROR`, meaning the previous commit missed to
set an error code in the common fallible codepath we wanted to know.
Besides `ERROR_UNIDENTIFIED_ERROR`, we're seeing `DETOUR_PATCHER_DO_RESERVE_ERROR`
in the telemetry, but having that code is not enough to pinpoint a falling
operation.
For further investigation, this patch adds ten more values to `DetourResultCode`.
`FUNCHOOKCROSSPROCESS_COPYSTUB_ERROR` is the last codepath we forgot to cover
in the previous commit. The values of `MMPOLICY_RESERVE_*` are to investigate
`DETOUR_PATCHER_DO_RESERVE_ERROR` in the MMPolicy level. In both cases, we add
the last Windows error code to `DetourError::mOrigBytes`.
Differential Revision: https://phabricator.services.mozilla.com/D92974
The previous commit d8315e4ed18d introduced a new telemetry field
in the launcher process ping to collect the assembly pattern of
a target function on detour failure, but most of the crash instances
do not have a value in the field. This means the failure happens
before or after `CreateTrampoline`.
To narrow down the root cause, this patch puts a fine-grained error value
in the "hresult" field instead of the hardcoded ERROR_UNIDENTIFIED_ERROR.
This patch also adds `IsPageAccessible` check before fetching data from
a different process because fetching data from an invalid address hits
`MOZ_RELEASE_ASSERT` in `EnsureLimit`, resulting in crash without sending
the launcher process failure.
Differential Revision: https://phabricator.services.mozilla.com/D91881
Many instances of the launcher failure ping indicate hooking NtMapViewOfSection
or LdrLoadDll failed. This is most likely caused by a third-party application
applying a hook onto the same target earlier than we do.
This patch is to add a new field "detour_orig_bytes" in the laucnher failure ping
to collect the first sixteen bytes of a detour target function. With this,
we can know whether those detour failures were caused by a third-party hook or not,
and if yes, what was the actual binary pattern.
Differential Revision: https://phabricator.services.mozilla.com/D89836
Many instances of the launcher failure ping indicate hooking NtMapViewOfSection
or LdrLoadDll failed. This is most likely caused by a third-party application
applying a hook onto the same target earlier than we do.
This patch is to add a new field "detour_orig_bytes" in the laucnher failure ping
to collect the first sixteen bytes of a detour target function. With this,
we can know whether those detour failures were caused by a third-party hook or not,
and if yes, what was the actual binary pattern.
Differential Revision: https://phabricator.services.mozilla.com/D89836
The earlier fix ea452bb92e6a proved the executable's imagebase in a child
process is not always the same as the local imagebase. This patch applies
the new approach to retieve the imagebase from a handle to all channels.
Interestingly, we observed the launcher failures at `VirtualProtectEx` only
when launching a sandboxed process, not when launching the browser process.
In the long term, we may need to take care of all `WriteProcessMemory` calls
for a child process for greater safety, but given that observation, this
patch only updates `RestoreImportDirectory` and `InitializeDllBlocklistOOP`.
Differential Revision: https://phabricator.services.mozilla.com/D90316
In most situations, JSONWriter users already know string lengths (either directly, or through `nsCString` and friends), so we should keep this information through JSONWriter and not recompute it again.
This also allows using JSONWriter with sub-strings (e.g., from a bigger buffer), without having to create null-terminated strings.
Public JSONWriter functions have overloads that accept literal strings.
Differential Revision: https://phabricator.services.mozilla.com/D86192
This patch adds a new property `process_type` to the launcher process failure
ping, indicating which process type the browser process failed to initialize
as a sandboxed process.
Depends on D83639
Differential Revision: https://phabricator.services.mozilla.com/D83640
This patch adds winlauncher's HandleLauncherError to DllServices
along with InitializeDllBlocklistOOPInternal so that SandboxBroker
can call HandleLauncherError.
Differential Revision: https://phabricator.services.mozilla.com/D83639
This patch defines a new macro `MOZ_USE_LAUNCHER_ERROR` and keeps
the use of `LauncherError` behind `MOZ_USE_LAUNCHER_ERROR` instead of
`MOZILLA_INTERNAL_API` so that we can selectively use `LauncherError`
in locations where `MOZILLA_INTERNAL_API` is defined.
Differential Revision: https://phabricator.services.mozilla.com/D83638
If the process was elevated due to AppCompatFlags, we should not
use LaunchUnelevated to launch the browser process because it starts
an infinite loop of process launch.
The fix is to make GetElevationState return a new elevation state
if RUNASADMIN is set in AppCompatFlags. With that state, we use
CreateProcessAsUser to launch the browser process.
Differential Revision: https://phabricator.services.mozilla.com/D80114
`BLOCK_WIN8_ONLY` was introduced by bug 1268470 to block klsihk64.dll only on
Win8. However, a new blocklist (bug 1445025) does wrong comparison on the OS
version, thus `BLOCK_WIN8_ONLY` has blocked modules on all platforms older than
Win10 including Win7 and Win8.1.
This patch corrects OS comparison and changes the flag to `BLOCK_WIN8_AND_OLDER`
to make it more handy. We also remove `BLOCK_WIN8PLUS_ONLY` which is never used.
Differential Revision: https://phabricator.services.mozilla.com/D78411
When the browser process starts a sandbox process, we copy the executable's IAT
for ntdll.dll into the new process to prevent DLL injection via IAT tampering as
the launcher process does. However, if IAT has been modified by a module injected
via `SetWindowHookEx`, the browser process cannot copy IAT because a modified IAT
is invalid in a different process, failing to start any sandbox processes.
The proposed fix is to cache IAT before COM initialization which may load
modules via `SetWindowHookEx` for the first time in the process.
Differential Revision: https://phabricator.services.mozilla.com/D73303
Since the test goes through all moz.build files disregarding DIRS and
the conditions that may disable directories, in some cases, moz.builds
can fail to be evaluated properly because of missing variables in
config.status. This time (because it's not the first), it's
LLVM_DLLTOOL.
After fixing that, it turns out many of the files/directories pointed to
by Files() directives were removed or moved.
While here, make the test script python3-ready.
Differential Revision: https://phabricator.services.mozilla.com/D70157
--HG--
extra : moz-landing-system : lando
This patch introduces a new DLL blocklist type `RedirectToNoOpEntryPoint`
which hooks a DLL's entrypoint into a no-op function. With this technique,
we give the injected DLL no chance to run its code though we allow it to be
loaded into the process.
This new blocklist type is intended to block a DLL which is injected by IAT
patching which was planted by a kernel callback routine for LoadImage. It's
because blocking such a DLL makes a new process fail to launch.
Differential Revision: https://phabricator.services.mozilla.com/D68348
--HG--
extra : moz-landing-system : lando
This patch introduces `Kernel32ExportsSolver` which calculates RVAs of
kernel32's functions and transfers them to a target process, where the
transferred RVAs are resolved into function addresses.
Depends on D68346
Differential Revision: https://phabricator.services.mozilla.com/D68347
--HG--
extra : moz-landing-system : lando
This patch moves the instantiation of `PEHeaders` from `CheckBlockInfo` to
`IsDllAllowed` so that `IsDllAllowed` can use an instance of `PEHeaders`.
Depends on D68342
Differential Revision: https://phabricator.services.mozilla.com/D68343
--HG--
extra : moz-landing-system : lando
This patch introduces a new DLL blocklist type `RedirectToNoOpEntryPoint`
which hooks a DLL's entrypoint into a no-op function. With this technique,
we give the injected DLL no chance to run its code though we allow it to be
loaded into the process.
This new blocklist type is intended to block a DLL which is injected by IAT
patching which was planted by a kernel callback routine for LoadImage. It's
because blocking such a DLL makes a new process fail to launch.
Differential Revision: https://phabricator.services.mozilla.com/D68348
--HG--
extra : moz-landing-system : lando
This patch introduces `Kernel32ExportsSolver` which calculates RVAs of
kernel32's functions and transfers them to a target process, where the
transferred RVAs are resolved into function addresses.
Depends on D68346
Differential Revision: https://phabricator.services.mozilla.com/D68347
--HG--
extra : moz-landing-system : lando
This patch moves the instantiation of `PEHeaders` from `CheckBlockInfo` to
`IsDllAllowed` so that `IsDllAllowed` can use an instance of `PEHeaders`.
Depends on D68342
Differential Revision: https://phabricator.services.mozilla.com/D68343
--HG--
extra : moz-landing-system : lando
Also adds missing includes in some files, these were previously only transivitely
included through mozilla/TypeTraits.h.
Differential Revision: https://phabricator.services.mozilla.com/D68561
--HG--
extra : moz-landing-system : lando