winapicode-security

Trying to set ProcessStrictHandleCheckPolicy returns 87 - Incorrect Function


I am trying to use SetProcessMitigationPolicy on Windows 10 to enable the ProcessStrictHandleCheckPolicy:

The process will receive a fatal error if it manipulates a handle that is not valid.

As a general rule, strict handle checking cannot be turned off once it is turned on. Therefore, when calling the SetProcessMitigationPolicy function with this policy, the values of the RaiseExceptionOnInvalidHandleReference and HandleExceptionsPermanentlyEnabled substructure members must be the same. It is not possible to enable invalid handle exceptions only temporarily.

I can enable a number of the other mitigations:

But ProcessStrictHandleCheckPolicy:

PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY policy;
policy.RaiseExceptionOnInvalidHandleReference = 1;
policy.HandleExceptionsPermanentlyEnabled = 1;

BOOL res = SetProcessMitigationPolicy(ProcessStrictHandleCheckPolicy, policy, sizeof(policy));

if (!res) 
   RaiseLastWin32Error();

fails with error code 87:

ERROR_INVALID_PARAMETER
The parameter is incorrect

What is wrong?

Bonus Chatter

The ProcessDynamicCodePolicy policy prevents an embedded web browser from running Javascript:

More Bonuser

I'm actually in Delphi, so the syntax is different from the above C/C++/C# pseudo-code:

type
    //ProcessStrictHandleCheckPolicy - The process will receive a fatal error if it manipulates an invalid handle. Useful for preventing downstream problems in a process due to handle misuse.
    PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY = record
        Flags: DWORD;
                //DWORD RaiseExceptionOnInvalidHandleReference : 1;
                //DWORD HandleExceptionsPermanentlyEnabled : 1;
                //DWORD ReservedFlags : 30;
    end;

procedure SetMitigationPolicy;
var
    policy: PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY;
    res: BOOL;
begin
    policy.Flags := $00000002;
    res := SetProcessMitigationPolicy(ProcessStrictHandleCheckPolicy, @policy, sizeof(policy));
    if not res then
        RaiseLastWin32Error;
end;

It doesn't change the question:

rolls the dice

Don't include delphi delphi-xe6 tags.

Bonus Reading


Solution

  • From the PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY documentation:

    As a general rule, strict handle checking cannot be turned off once it is turned on. Therefore, when calling the SetProcessMitigationPolicy function with this policy, the values of the RaiseExceptionOnInvalidHandleReference and HandleExceptionsPermanentlyEnabled substructure members must be the same. It is not possible to enable invalid handle exceptions only temporarily.

    When you wrote:

    policy.Flags := $00000002;
    

    You only set the HandleExceptionsPermanentlyEnabled flag, but not the RaiseExceptionOnInvalidHandleReference flag. It should be this instead, which sets both flags:

    policy.Flags := $00000003;
    

    I'm fairly sure that you never actually ran your C++ code because it does not compile. If you fix the obvious compilation errors, then it will run successfully.

    #define  _WIN32_WINNT 0x0602
    
    #include <Windows.h>
    #include <Processthreadsapi.h>
    #include <iostream>
    
    int main()
    {
        PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY policy = { 0 };
        policy.RaiseExceptionOnInvalidHandleReference = 1;
        policy.HandleExceptionsPermanentlyEnabled = 1;
    
        BOOL res = SetProcessMitigationPolicy(ProcessStrictHandleCheckPolicy, &policy, 
            sizeof(policy));
        DWORD err = 0;
        if (!res)
            err = GetLastError();
        std::cout << res << ", " << err;
    }
    

    This program outputs 1, 0 as expected. If you add

    policy.Flags = 0x00000002;
    

    immediately before the call to SetProcessMitigationPolicy, then the output is 0, 87.