造成COM方法返回的Spectre / Meltdown Patch
我在一个大量使用COM的项目上工作,新的Spectre / Meltdown补丁毫无疑问地与程序中的通信混淆了。
我怎么知道? 我重新映像了Windows修补程序不存在的情况下(2017年5月)。 我安装了我的程序,一切正常。 然后我下载了所有必需的更新。 该程序不再有效。 然后,我只卸载了Meltdown / Spectre修补程序(2018-01年基于x64的系统的Windows 10版本1507累积更新(KB4056893)),程序返回到正常行为。
我将调试器连接到我的程序并将其追溯到这段代码。
INvRtrControl4Itf * poRouterControl = GetNvRtrControl4();
if(poRouterControl)
{
//the following line of code always returns E_ACCESSDENIED
HRESULT hr = poRouterControl->GetXPTExtendedInfoForOutputs(lNumPorts, poOutputPorts, poXPTAndLPRInfo, peStatus);
if(FAILED(hr))
{
ConnectToRouterControl();
poRouterControl->Release();
return hr;
}
poRouterControl->Release();
}
未修补系统上的Windows调试器:
poRouterControl->GetXPTExtendedInfoForOutputs returns S_OK
修补系统上的Windows调试器:
poRouterControl->GetXPTExtendedInfoForOutputs returns E_ACCESSDENIED
我有一个COM服务器A尝试与COM服务器B通信,两者都具有相同的权限(SYSTEM)。 在PATCHED系统上,当A从COM接口INvDevControl2Itf调用一个方法时,该方法由服务器B调用,没有错误。 当同一个服务器A尝试从进程B上的另一个接口INvRtrControl4Itf调用一个方法时,E_ACCESSDENIED被返回,我从来没有通过COM接口。 在UN-PATCHED系统上,一切都按预期工作。
有没有人遇到过这个问题,还有COM和新的Spectre / Meltdown补丁? 我会继续寻找原因,但是没有安装补丁程序,相同的代码运行得很好。 不过,客户最终会希望更新他们的系统,所以我不建议也不想让他们永远不要安装该补丁。
借助Patch Itself上的Windows支持页面,我能够通过更改COM服务的CoInitializeSecurity()方法调用中的某些代码来解决COM服务无法调用方法GetXPTExtendedInfoForOutputs的问题
hRes = CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_NONE,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL);
至
hRes = CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_CALL, //<----------- changed
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL);
虽然它解决了这个问题,但知道其中一些接口与原始代码一起工作得很好,而其他像INvRtrControl4Itf失败的问题有些麻烦。 此外,我不需要更改与其通信的其他COM服务中的CoInitializeSecurity方法初始化,而只需要调用者COM服务。 其他COM服务仍然可以使用RPC_C_AUTHN_LEVEL_NONE初始化,我的程序和以前一样工作。
但是,我确实更改了所有使用RPC_C_AUTHN_LEVEL_CALL的CoInitializeSecurity方法调用,这会减少未来E_ACCESSDENIED结果的可能性。 不幸的是,现在每次调用RPC服务器都需要身份验证,因此我认为我的程序性能可能会受到一些影响。 我怀疑这将是什么关切。
也许这就是为什么有些人在用Spectre / Meltdown补丁更新系统时注意到性能受到影响......只是一个想法。
链接地址: http://www.djcxy.com/p/41055.html上一篇: Spectre/Meltdown Patch Causing COM Method to Return E
下一篇: Inserting html tags between C# block code in cshtml file