State Separation
State Separation is an improved servicing and security model that uses clearer security boundaries to:
- Help increase security to key system areas
- Enable faster and cleaner updates and system resets
This model is used in all Factory OS images. The security boundaries are classified by the following states:
State | Description | Examples |
---|---|---|
Immutable | This area can't be changed permanently, except by the operating system itself. |
|
Mutable, high value | You can make changes and expect them to persist after a reboot or an update, but not after a system reset |
|
Mutable, low value | You can make changes, but they'll disappear after a reboot or a system reset. | Some components may need to write to registry hives such as HKLM\SYSTEM and HKLM\SOFTWARE . These registry areas are loaded as volatile, so your components can still perform the write operation for a particular runtime. Upon the next reboot, the changes will disappear. |
User data | Can be changed. Each user data profile is encrypted on its own partition, so the changes only affect the user is logged in |
|
For factory tests, it's OK to store log files and other test files in either the data partition or in %PROGRAMDATA%
.
State separation violations
State separation violations occur when:
- A component attempts to write to the filesystem on the MainOS volume.
- A component writes to the
HKLM\SYSTEM
orHKLM\SOFTWARE
registry hives.
To help you develop components that meet these rules, Windows can log whenever a component attempts to write to either of these locations.
Note, just because Windows tracks a write operation doesn't necessarily mean there's a problem: a component may sometimes intentionally write to the HKLM\SYSTEM
or HKLM\SOFTWARE
registry hives expecting the change to be volatile.
Instrumentation
There's a few methods to gather logs of registry and file system activity. Determining the proper method to use depends on use case, and when in the boot sequence your driver becomes active. Below is a table that summarizes when to use each method to find state separation and driver isolation violations.
Method | When to Run? | What does it find? |
---|---|---|
Early Boot Auto-Logger | Want to find file violations that cannot be found with Driver Verifier or want to see file and registry violations in the same trace | All file violations and most registry violations |
On-Demand Logger | Want to find file violations that cannot be found with Driver Verifier or want to see file and registry violations in the same trace | All file violations and most registry violations |
Boot Trace | Want to have detailed stack information leading up to a violation | All file and registry operations, regardless of if they are a violation or not |
Driver Verifier Driver Isolation Checks | Want to find all registry violations during device bring-up, generic driver testing, and/or certification testing | No file violations and all registry violations |
Realtime view of violations
The easiest method of tracking state separation violations is to review Event Traces for Windows (ETW) real-time through the Windows Device Portal.
Note
The filter driver that provides this telemetry may load after your component. If your component is exercised early in the boot process, you'll need to look at the next section.
- Log in to the Windows Device Portal, on the device under test
- Go to the ETW Logging tab on the left.
- Under Custom Provider, enable the following provider: d6e1490c-c3a6-4533-8de2-18b16ce47517 .
- Repro your scenario. Violations will appear in the table.
- When you've collected sufficient data, click Save to file to get a text file (.csv) containing the captured violations. It's often easier to work with the downloaded data than do a real-time analysis.
Early boot AutoLogger
Use an early boot AutoLogger to capture ETW traces for operations performed early in the boot path:
Run Tracelog to configure the autologger to listen to the provider GUID: d6e1490c-c3a6-4533-8de2-18b16ce47517.
Set buffers to 128 kilobytes, with a minimum of 12 buffers and a max of 34 buffers (lower values may cause events to be dropped).
For the session guid, you can generate a GUID using
uuidgen
and then add a number sign (#) before it, or you can provide a filename that includes a GUID.You can save the logfile anywhere, though we recommend using a location in the user or app data folders, such as
-f %ProgramData%\Fabrikam\log.etl
.Tracelog.exe -addautologger StateSeparationViolationsAutologger -sessionguid #aabbccdd-1234-5678-90ab-a00bb00ccdd -f %ProgramData%\Fabrikam\log.etl -guid #d6e1490c-c3a6-4533-8de2-18b16ce47517 -b 128 -min 12 -max 34
Reboot the device to begin the AutoLogger trace session
Stop the autologger:
Tracelog.exe -stop StateSeparationViolationsAutologger
Get the ETL file and review the data:
a. Capture the value of the device's ProgramData directory (for example,
E:\ProgramData
).cmd-device -InformationVariable echoInfo echo %ProgramData% $deviceProgramData = $echoInfo[0]
b. Use this value to copy the ETL file from the device to your local PC. Example:
PS C:\> getd E:\ProgramData\Fabrikam\log.etl C:\hostdir\log.etl
Review the Trace Logging activity data using Windows Performance Analzyer (WPA) or other tools.
On-demand logger
Use an on-demand logger to capture an on-demand ETW trace.
Configure a logging session to listen to provider GUID d6e1490c-c3a6-4533-8de2-18b16ce47517:
Tracelog.exe -start StateSeparationViolations -f <path to save ETL> -guid #d6e1490c-c3a6-4533-8de2-18b16ce47517
Repro your scenario or run your test (as long as the device doesn't reboot).
Stop the logging session.
Tracelog.exe -stop StateSeparationViolations
Copy the ETL file off of the device.
PS C:\> getd C:\ProgramData\Fabrikam\log.etl C:\hostdir\log.etl
Open the log file and review the Trace Logging activity data using Windows Performance Analyzer.
Boot trace
With an early boot ETW trace set up correctly, all registry operations, and/or file operations can be captured in a trace and have stacks captured for each operation detailing the code path leading to that registry operation.
Register boot trace (either registry, fileio, or both)
wpr -boottrace -addboot registry wpr -boottrace -addboot fileio
Reboot the device to begin capturing the trace.
Connect to the device with TShell again.
Stop the trace:
wpr -boottrace -stopboot <path where to write ETL>
Copy the ETL file off of the device.
PS C:\> getd C:\<path on device to the>\log.etl C:\hostdir\log.etl
Open the log file and open the Trace Logging activity data using Windows Performance Analyzer.
In WPA, tell it to load symbols so the binary being investigated can be resolved in the stack traces and then open up a Registry summary table.
We recommend that you filter the table to only show operations to the SYSTEM and SOFTWARE hives. If viewing the “base key tree" column, expand REGISTRY and then MACHINE. Multi-select both SYSTEM and SOFTWARE, right-click and select Filter To Selection.
We recommend that you filter the table to only operations where the stack involves the binary being investigated. This filtering can be done on top of the filtering to only the SYSTEM and SOFTWARE hive recommended above. Click in the Stack column and open the search box. Enter the name of the binary being investigated and click Find All. Right-click on one of the highlighted lines in the stack that contained the binary name, and select Filter To Selection.
Driver Verifier driver isolation checks
Driver Verifier (DV) is a tool that ships with Windows that is used to monitor drivers for improper function calls or actions that may corrupt the system. Starting in OS build 19568, Driver Verifier has new functionality to support developers of Windows Drivers by monitoring for violations of Driver Package Isolation requirements. Driver package isolation is the key requirement drivers must adhere to on Factory OS systems in order to adhere to state separation requirements.
Driver Verifier will monitor for improper registry reads and writes that are not allowed on Factory OS systems. Use this tool early on in driver development to understand and fix where your component is violating driver isolation requirements.
Syntax:
Note
If enabling on a Factory OS system, please see Connect using SSH for connecting to the Factory OS system remotely via SSH
verifier /rc 33 36 /driver myDriver.sys
This will enable the driver isolation checks on your targeted driver (myDriver.sys). You can also select multiple drivers by separating the list with a space:
verifier /rc 33 36 /driver myDriver1.sys myDriver2.sys
A reboot will be required for the verification settings to be enabled. You can do so by specifying:
shutdown /r /t 0
Expected Behavior - Telemetry Mode:
During initial stages of driver bring-up, the recommended behavior for these checks is telemetry mode. This is the default behavior and will provide a way for developers to view all violations without a bugcheck disrupting progress.
It is recommended that DV driver isolation checks are enabled using the syntax specified in the section above with a kernel debugger attached. After a reboot has enabled the DV settings, you will be able to see violations in the kernel debugger output.
Below are a couple example scenarios of a driver violating driver isolation requirements and what typical output would look like:
Scenario: ZwCreateKey using full absolute path:
"DRIVER_ISOLATION_VIOLATION: <driver name>: Registry operations should not use absolute paths. Detected creation of unisolated registry key '\Registry\Machine\SYSTEM'"
Scenario: ZwCreateKey using path relative to a handle that is not from approved API:
"DRIVER_ISOLATION_VIOLATION: <driver name>: Registry operations should only use key handles returned from WDF or WDM APIs. Detected creation of unisolated registry key '\REGISTRY\MACHINE\SYSTEM\SomeKeyThatShouldNotExist'"
Leverage telemetry mode to establish a baseline of all violations for your component and begin to fix them one-by-one, testing as you go.
Expected Behavior - Bucheck Mode:
Further along in the driver development process, it can be valuable to enable the driver isolation checks in a mode that will make a violation obvious. DV can be configured to induceabugcheck when a violation occurs.
This will generate a memory dump that gives precise details of where the violation occurred. To enable DV in bugcheck mode, use the following syntax:
verifier /onecheck /rc 33 36 /driver myDriver1.sys
This mode is useful when the driver is nearing production-readiness and is undergoing final stages of validation and testing.
Maximizing Code Paths:
DV driver isolation rules can be enabled during an IHV's execution of their existing testing frameworks. This will help maximize the code paths exercised by the driver being tested.
Device Fundamentals tests via the command line are a good baseline of tests to exercise typical code paths for your driver. Developers can enable these tests with DV driver isolation checks to maximize the potential of catching driver isolation violations as early as possible.
Development Mode: disable enforcement
For development purposes, you can turn off enforcement of State Separation by running in State Separation Dev Mode. This lets you develop, test, and run apps and drivers (such as factory test apps) that don't comply with requirements.
In Development Mode:
- The MainOS partition is writable.
- Changes in
HKLM\SYSTEM
, andHKLM\SOFTWARE
persist across reboots. - Windows continues to monitor for activities that would otherwise break State Separation rules.
You can configure Development mode at image creation time by replacing the feature: STATESEPARATION_ON
with STATESEPARATION_DEVMODE
.
The following table details the differences between each mode.
State separation mode | Immutable filesystem access | Immutable registry access |
---|---|---|
Enforced Mode | Writes not allowed | Registry changes do not persist across reboot |
Violation warning in ETW and debugger output | Violation warning in ETW and debugger output | |
Dev Mode | Read/write allowed | Registry changes persist across reboot |
Violation warning in ETW and debugger output | Violation warning in ETW and debugger output |