Closed Bug 1526383 Opened 3 years ago Closed 3 years ago

nsWindowsDllInterceptor porting to aarch64

Categories

(Core :: mozglue, enhancement, P1)

ARM64
Windows
enhancement

Tracking

()

RESOLVED FIXED
mozilla67
Tracking Status
firefox67 --- fixed

People

(Reporter: bugzilla, Assigned: bugzilla)

References

(Blocks 1 open bug)

Details

Attachments

(2 files)

We don't need to support the full set of functions that we intercept on other platforms, but according to my analysis, at the very least we need:

ntdll!LdrLoadDll
ntdll!LdrUnloadDll
ntdll!LdrResolveDelayLoadedAPI
user32!GetWindowInfo

If we're shipping a native aarch64 binary then it'll only be possible for it to load native aarch64 DLLs, right? That seems like it probably reduces the attack surface significantly for now. (Until the usual suspects get around to shipping aarch64 versions of their software.)

DLL blocking is already out of scope for aarch64; these hooks are required for other reasons.

The good news is that these functions all have a pretty standard prolog for setting up their stack frames.

The bad news is that, depending on the distance of the hook function from the current PC, the branch could consume up to 16 bytes, which may be more than the prolog.

In the case of ntdll!LdrUnloadDll, we have a 3 instruction prolog, and then the 4th instruction is PC-relative!
We need to be able to recognize when an instruction is PC-relative and make the appropriate adjustments when copying it into the trampoline. The number of instructions that do this is small (and for the limited scope of this bug, we really only care about ADRP), but this does need to be handled and is the only complicated part of this patch.

I have a preliminary patch that works for the essentials; TestDllInterceptor now passes for those four specific functions!

Having said that, I need to do some additional work to ensure that we fail out if we encounter something unfamiliar.

See https://static.docs.arm.com/ddi0487/da/DDI0487D_a_armv8_arm.pdf for the ARMv8 architecture reference manual -- it contains information about the instruction encodings.

This patch doesn't cover all possible functions for which we currently
instantiate interceptors inside Firefox/Gecko. Rather than asserting, we just
fail in those cases (at least until we have full coverage of existing uses).

This is okay, as for the upcoming milestone 2 of aarch64 builds, we are most
concerned with successfully being able to hook the following functions:

ntdll!LdrLoadDll
ntdll!LdrUnloadDll
ntdll!LdrResolveDelayLoadedAPI
user32!GetWindowInfo

So, within that context, the aarch64 implementation is fairly simple:

Each instruction is 4-bytes wide. We iterate down each instruction, and if the
current instruction is not PC-relative, we just copy it verbatim. If we
encounter an instruction that is PC-relative, we either decode it and
rewrite it inside the trampoline, or we fail. For the purposes of milestone 2,
the only instruction that is essential to decode is ADRP.

In bug 1526016 I modify TestDllInterceptor to exclude functions that are not
yet supported by this patch.

Pushed by aklotz@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/fae2ad1c3dc6
Add essential arm64 support to nsWindowsDllInterceptor; r=handyman
Status: ASSIGNED → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla67
You need to log in before you can comment on or make changes to this bug.