Information Technology Reference
In-Depth Information
Figure 4. Protection of the kernel address space. Drivers can read and write their private heap and
stacks, but only read from the kernel.
two types of wrappers: kernel wrappers , which
are called by drivers to execute kernel-supplied
functions; driver wrappers , which are called by
the kernel to execute driver-supplied functions. In
both cases, a wrapper functions as an XPC stub
that appears to the caller as if it were the target
procedure in the called domain.
Both wrapper types perform the body of their
work within the kernel protection domain. There-
fore, the domain change occurs at a different point
depending on the direction of transfer, as shown
in Figure 3. When a driver calls a kernel wrapper,
the wrapper performs an XPC on entry so that the
body of the wrapper (i.e., object checking, copying,
etc.) can execute in the kernel's domain. Once the
wrapper's work is done, it calls the target kernel
function directly with a regular procedure call.
In the opposite direction, when the kernel calls a
driver wrapper, the wrapper executes within the
kernel's domain. When it is done, the wrapper
performs an XPC to transfer to the target function
within the driver.
Wrappers perform four basic tasks. First, wrap-
pers implement the shadow driver tap mechanism
(described later in this chapter). Second, wrappers
check parameters for validity by verifying with the
object tracker and memory manager that pointers
are valid. Third, they implement call-by-value-
result semantics for XPC, by creating a copy of
kernel objects on the local heap or stack within
the driver's protection domain. These semantics
ensure that updates to kernel objects are trans-
actional, because they are only applied after the
driver completes, when the wrappers copy the
results back to the kernel. Fourth, wrappers per-
form an XPC into the kernel or driver to execute
the desired function, as shown in Figure 3.
While wrappers must copy data between pro-
tection domains, no marshaling or unmarshaling
is necessary, because the driver and kernel share
the same address space. Instead, wrappers may
directly allocate and reference memory in either
the kernel or the driver protection domains. The
code for synchronizing simple objects is placed
directly in the wrappers, while the object tracker
provides synchronization routines for complex
objects with many pointers. As an optimization,
wrappers may pass parameters that are only read
but not written by drivers without modification,
as any attempt to modify the parameter will cause
a memory access fault.
To improve performance, the wrappers rely on
several techniques for moving complex objects
between protection domains. In some cases, Nooks
copies objects into the driver's protection domain,
following embedded pointers as appropriate. It
is generally unnecessary to copy the complete
transitive closure of an object; while drivers
read pointers more than one level removed from
a parameter, they generally do not write to them.
Search WWH ::




Custom Search