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.
  • The operating system binaries
  • Registry hives: HKLM\SYSTEM and HKLM\SOFTWARE
Mutable, high value You can make changes and expect them to persist after a reboot or an update, but not after a system reset
  • System settings
  • Log files
  • Program data.
    Note: Use APIs or environment variables such as %PROGRAMDATA% to refer to these folders. If your code includes absolute paths like C:\Program Data\ or writes to other system areas, the write operation may fail with an access violation.
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
  • NT User Profile
  • Registry hive: HKCU

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 or HKLM\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.

  1. Log in to the Windows Device Portal, on the device under test
  2. Go to the ETW Logging tab on the left.
  3. Under Custom Provider, enable the following provider: d6e1490c-c3a6-4533-8de2-18b16ce47517 .
  4. Repro your scenario. Violations will appear in the table.
  5. 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:

  1. Connect to the device with TShell.

  2. 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
    
  3. Reboot the device to begin the AutoLogger trace session

  4. Connect to the device with TShell.

  5. Stop the autologger:

    Tracelog.exe -stop StateSeparationViolationsAutologger
    
  6. 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
    
  7. 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.

  1. 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
    
  2. Repro your scenario or run your test (as long as the device doesn't reboot).

  3. Stop the logging session.

    Tracelog.exe -stop StateSeparationViolations
    
  4. Copy the ETL file off of the device.

    PS C:\> getd C:\ProgramData\Fabrikam\log.etl C:\hostdir\log.etl
    
  5. 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.

  1. Connect to the device with TShell

  2. Register boot trace (either registry, fileio, or both)

    wpr -boottrace -addboot registry
    wpr -boottrace -addboot fileio
    
  3. Reboot the device to begin capturing the trace.

  4. Connect to the device with TShell again.

  5. Stop the trace:

    wpr -boottrace -stopboot <path where to write ETL>
    
  6. Copy the ETL file off of the device.

    PS C:\> getd C:\<path on device to the>\log.etl C:\hostdir\log.etl
    
  7. Open the log file and open the Trace Logging activity data using Windows Performance Analyzer.

  8. 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, and HKLM\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