Child processes now report loaded DLLs to the parent by section HANDLE instead
of by filename. The DLL blocklist's NtMapViewOfSection hook already receives
the section a module is being mapped from, so it duplicates that section,
read-only, onto the ModuleLoadInfo for the load. The parent identifies the
module from the HANDLE.
Because the section outlives the view, this also fixes reporting for two kinds
of load: a module the blocklist rejected, which is unmapped immediately, and a
module unloaded before the parent processed the batch. Previously, either
could be deleted before the parent had a chance to consider them.
A handle cannot be forged into a reference to a different file and a child can
only send one it holds. ValidateAndResolveModuleSection sanity checks:
1. The section must map, and the view must be MEM_IMAGE. A data section can
be made over any openable file but an image section means the kernel
accepted the file as a PE and the child's image-load policy applied to it.
2. The file must not be on a remote device.
3. The file must not carry a mandatory integrity label below medium.
These checks replicate the checks of the MITIGATION_IMAGE_LOAD_NO_REMOTE and
MITIGATION_IMAGE_LOAD_NO_LOW_LABEL child sandbox behaviors. A child
can create a non-IMAGE section over any file it can open, so what it hands us
is not bounded by the image-load policy. The check avoid considering such
files at all. This currently applies to all child processes: content, gpu,
RDD, socket, utility (all kinds), and GMP. All have these sandbox mitigations.
Also fixes a couple of ways that a version resource could misuse VerQueryValueW's
output in the parent: a zero length underflowing to SIZE_MAX in
QueryStringValue and a too-short buffer dereference in GetFromImage.
Differential Revision: https://phabricator.services.mozilla.com/D324703