ANNOUNCEMENT: Registry Filtering Issues Identified at Filter Plugfest 21 and Possible

ANNOUNCEMENT: Registry Filtering Issues Identified at Filter Plugfest 21 and Possible Workarounds

These issues and workarounds are for Windows Vista, Windows Server 2008, Windows 7, and Windows Server 2008 R2.

*** Note: All fixes mentioned are being considered for the future with NO guarantees as to if and when the fixes will be made and whether they will be backported to downlevel OS?s. ***

  1. Bug: NtQueryObject cannot be filtered

Registry filtering does not provide a way to intercept NtQueryObject which can retrieve information about registry keys such as the key path. Filter drivers trying to do registry virtualization or redirection will need to hook this call themselves for now.

Workaround: Hook call from user mode

Fix: Registry will provide a callback for name queries.

  1. Bug: NtNotifyChangeKeyValue cannot be filtered

There is no way to filter this operation and no workarounds that account for all corner cases.

Fix: Registry will provide a callback mechanism to handle this operation.

  1. Bug: ZwRenameKey is not exported

Fix: ZwRenameKey will be exported.

  1. Bug: CreateKey callback issued from unload hive before pre-unloadhive callback can cause the unload operation to fail

At the start of NtUnloadKey2, an ObOpenObjectByName call on the root key of the hive happens before the Pre-UnloadHive callback. The ObOpenObjectByName call triggers a CreateKey callback but the CloseHandle callback is not triggered until the end of the unload operation. If the filter driver opens a handle to a key in the same hive that is about to be unloaded in the CreateKey callback, the unload hive operation will fail because hives with open handles cannot be unloaded.

Workaround: Filter drivers that hit this problem can work around it by keeping track of the last CreateKey callback on each thread (PsGetCurrentThread) and record the handles that were opened in that callback. The particular CreateKey callback triggered by ObOpenObjectByName will be trying to open the root key of the hive. If the very next callback on the thread is a Pre-UnloadHive callback then the handles opened to any keys in the hive being unloaded during that last CreateKey callback need to be closed. Please apply this workaround carefully so that your filter driver is not broken when this bug is fixed.

Fix: Either the Pre-UnloadHive callback will be called before the ObOpenObjectByname or the ObOpenObjectByName will not be called at all.

  1. Info: Handling SamDesired with value MAXIMUM_ALLOWED

In the Pre callback for a CreateKey or OpenKey operation, if the SamDesired field is MAXIMUM_ALLOWED and the filter driver intends to return STATUS_CALLBACK_BYPASS, the filter driver needs to fill the GrantedAccess field of the pre information structure with the “real” rights that correspond to MAXIMUM_ALLOWED for the given security context. You can get this information using the last parameter of ObReferenceObjectByHandle.

ObReferenceObjectByHandle (
__in HANDLE Handle,
__in ACCESS_MASK DesiredAccess,
__in_opt POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__deref_out PVOID *Object,
__out_opt POBJECT_HANDLE_INFORMATION HandleInformation

ULONG HandleAttributes;
ACCESS_MASK GrantedAccess;

The OBJECT_HANDLE_INFORMATION structure is not exported. The GrantedAccess member will be set with the access granted. Please add the OBJ_FORCE_ACCESS_CHECK flag to the HandleAttributes parameter if the previous mode is user mode (more detail below).

  1. Info: Use the OBJ_FORCE_ACCESS_CHECK flag when acting on behalf of a user mode component

When a registry filter drivers calls a function that takes in a ULONG HandleAttributes or a POBJECT_ATTRIBUTES ObjectAttributes parameter, pass in the OBJ_FORCE_ACCESS_CHECK flag if the call is done on behalf of a user mode component. The OBJ_FORCE_ACCESS_CHECK flag tells the routine that opens the handle to enforce all access checks for the object even though the function is called from kernel mode by the filter driver.

  1. Info: Pre-CloseHandle callback

In the Pre-CloseHandle callback, the filter driver should not assume that the Object parameter passed in through the pre information structure is valid from the Object Manager’s perspective. That means Ob functions such as ObOpenObjectByPointer should not be called on Object or a bugcheck may result. Cm functions that take in an object pointer are still safe to call, such as CmCallbackGetKeyObjectID.

  1. Info: Issues in registry filtering version 1.0 that have been fixed in version 1.1

Callback Version 1.1 is available in Windows 7 and Windows Server 2008 R2. It is NOT available on Vista or Windows Server 2008 as of Service Pack 2.

  1. In the post-notification phase for a create or open key operation, the PostInfo->Object field might not be NULL even if the operation was unsuccessful as indicated by PostInfo->ReturnStatus. This problem happens when there are multiple registry filter drivers registered and one of the drivers blocks the operation in the pre-notification phase by returning a nonsuccess status. Filter drivers that are at higher altitudes will receive a post-notification where PostInfo->ReturnStatus is the nonsuccess status value but PostInfo->Object will not be NULL. PostInfo->Object in this case will be equal to PostInfo->PreInfo->RootObject.

  2. In version 1.0, an uncatched exception in a registry callback routine will be swallowed by the system. In version 1.1 this has been changed so an uncatched exception will cause the machine to bugcheck. NOTE: While bugchecking the system is not a good thing to do, we do not recommend putting your entire callback routine in one big try-except block and swallow legitimate exceptions like possible pool corruptions. Please keep what you wrap with a try-except block to the bare minimum.

*** This posting is provided “AS IS” with no warranties, and confers no Rights. ***