mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
runner: initialize COM security, so toast notifications work in elevated context from non-admin account (#5314)
This commit is contained in:
67
src/common/comUtils.cpp
Normal file
67
src/common/comUtils.cpp
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include <Sddl.h>
|
||||||
|
|
||||||
|
#include <wil/resource.h>
|
||||||
|
|
||||||
|
#include "comUtils.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
bool initializeCOMSecurity(const wchar_t* securityDescriptor)
|
||||||
|
{
|
||||||
|
PSECURITY_DESCRIPTOR self_relative_sd{};
|
||||||
|
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(securityDescriptor, SDDL_REVISION_1, &self_relative_sd, nullptr))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto free_relative_sd = wil::scope_exit([&] {
|
||||||
|
LocalFree(self_relative_sd);
|
||||||
|
});
|
||||||
|
|
||||||
|
DWORD absolute_sd_size = 0;
|
||||||
|
DWORD dacl_size = 0;
|
||||||
|
DWORD group_size = 0;
|
||||||
|
DWORD owner_size = 0;
|
||||||
|
DWORD sacl_size = 0;
|
||||||
|
|
||||||
|
if (!MakeAbsoluteSD(self_relative_sd, nullptr, &absolute_sd_size, nullptr, &dacl_size, nullptr, &sacl_size, nullptr, &owner_size, nullptr, &group_size))
|
||||||
|
{
|
||||||
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typed_storage<SECURITY_DESCRIPTOR> absolute_sd{ absolute_sd_size };
|
||||||
|
typed_storage<ACL> dacl{ dacl_size };
|
||||||
|
typed_storage<ACL> sacl{ sacl_size };
|
||||||
|
typed_storage<SID> owner{ owner_size };
|
||||||
|
typed_storage<SID> group{ group_size };
|
||||||
|
|
||||||
|
if (!MakeAbsoluteSD(self_relative_sd,
|
||||||
|
absolute_sd,
|
||||||
|
&absolute_sd_size,
|
||||||
|
dacl,
|
||||||
|
&dacl_size,
|
||||||
|
sacl,
|
||||||
|
&sacl_size,
|
||||||
|
owner,
|
||||||
|
&owner_size,
|
||||||
|
group,
|
||||||
|
&group_size))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !FAILED(CoInitializeSecurity(
|
||||||
|
absolute_sd,
|
||||||
|
-1,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
|
||||||
|
RPC_C_IMP_LEVEL_IDENTIFY,
|
||||||
|
nullptr,
|
||||||
|
EOAC_DYNAMIC_CLOAKING | EOAC_DISABLE_AAA,
|
||||||
|
nullptr));
|
||||||
|
}
|
||||||
3
src/common/comUtils.h
Normal file
3
src/common/comUtils.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
bool initializeCOMSecurity(const wchar_t* securityDescriptor);
|
||||||
@@ -116,19 +116,6 @@ struct typed_storage
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Callable>
|
|
||||||
struct on_scope_exit
|
|
||||||
{
|
|
||||||
Callable _f;
|
|
||||||
on_scope_exit(Callable f) :
|
|
||||||
_f{ std::move(f) } {}
|
|
||||||
|
|
||||||
~on_scope_exit()
|
|
||||||
{
|
|
||||||
_f();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class... Ts>
|
template<class... Ts>
|
||||||
struct overloaded : Ts...
|
struct overloaded : Ts...
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -120,6 +120,7 @@
|
|||||||
<ClInclude Include="animation.h" />
|
<ClInclude Include="animation.h" />
|
||||||
<ClInclude Include="appMutex.h" />
|
<ClInclude Include="appMutex.h" />
|
||||||
<ClInclude Include="async_message_queue.h" />
|
<ClInclude Include="async_message_queue.h" />
|
||||||
|
<ClInclude Include="comUtils.h" />
|
||||||
<ClInclude Include="d2d_svg.h" />
|
<ClInclude Include="d2d_svg.h" />
|
||||||
<ClInclude Include="d2d_text.h" />
|
<ClInclude Include="d2d_text.h" />
|
||||||
<ClInclude Include="d2d_window.h" />
|
<ClInclude Include="d2d_window.h" />
|
||||||
@@ -159,6 +160,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="animation.cpp" />
|
<ClCompile Include="animation.cpp" />
|
||||||
|
<ClCompile Include="comUtils.cpp" />
|
||||||
<ClCompile Include="d2d_svg.cpp" />
|
<ClCompile Include="d2d_svg.cpp" />
|
||||||
<ClCompile Include="d2d_text.cpp" />
|
<ClCompile Include="d2d_text.cpp" />
|
||||||
<ClCompile Include="d2d_window.cpp" />
|
<ClCompile Include="d2d_window.cpp" />
|
||||||
|
|||||||
@@ -129,6 +129,9 @@
|
|||||||
<ClInclude Include="processApi.h">
|
<ClInclude Include="processApi.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="comUtils.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="LowlevelKeyboardEvent.h">
|
<ClInclude Include="LowlevelKeyboardEvent.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -213,8 +216,11 @@
|
|||||||
<ClCompile Include="RcResource.cpp">
|
<ClCompile Include="RcResource.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="comUtils.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <common/RestartManagement.h>
|
#include <common/RestartManagement.h>
|
||||||
#include <common/appMutex.h>
|
#include <common/appMutex.h>
|
||||||
#include <common/processApi.h>
|
#include <common/processApi.h>
|
||||||
|
#include <common/comUtils.h>
|
||||||
|
|
||||||
#include "update_state.h"
|
#include "update_state.h"
|
||||||
#include "update_utils.h"
|
#include "update_utils.h"
|
||||||
@@ -299,6 +300,18 @@ void RequestExplorerRestart()
|
|||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||||
{
|
{
|
||||||
winrt::init_apartment();
|
winrt::init_apartment();
|
||||||
|
const wchar_t* securityDescriptor =
|
||||||
|
L"O:BA" // Owner: Builtin (local) administrator
|
||||||
|
L"G:BA" // Group: Builtin (local) administrator
|
||||||
|
L"D:"
|
||||||
|
L"(A;;0x7;;;PS)" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Personal self
|
||||||
|
L"(A;;0x7;;;IU)" // Access allowed on COM_RIGHTS_EXECUTE for Interactive Users
|
||||||
|
L"(A;;0x3;;;SY)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Local system
|
||||||
|
L"(A;;0x7;;;BA)" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Builtin (local) administrator
|
||||||
|
L"(A;;0x3;;;S-1-15-3-1310292540-1029022339-4008023048-2190398717-53961996-4257829345-603366646)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Win32WebViewHost package capability
|
||||||
|
L"S:"
|
||||||
|
L"(ML;;NX;;;LW)"; // Integrity label on No execute up for Low mandatory level
|
||||||
|
initializeCOMSecurity(securityDescriptor);
|
||||||
|
|
||||||
if (launch_pending_update())
|
if (launch_pending_update())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include <common/dpi_aware.h>
|
#include <common/dpi_aware.h>
|
||||||
#include <common/common.h>
|
#include <common/common.h>
|
||||||
#include <Sddl.h>
|
#include <common/comUtils.h>
|
||||||
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
@@ -493,8 +493,10 @@ void parse_args()
|
|||||||
LocalFree(argument_list);
|
LocalFree(argument_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initialize_com_security_policy_for_webview()
|
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
|
||||||
{
|
{
|
||||||
|
Trace::RegisterProvider();
|
||||||
|
CoInitialize(nullptr);
|
||||||
const wchar_t* security_descriptor =
|
const wchar_t* security_descriptor =
|
||||||
L"O:BA" // Owner: Builtin (local) administrator
|
L"O:BA" // Owner: Builtin (local) administrator
|
||||||
L"G:BA" // Group: Builtin (local) administrator
|
L"G:BA" // Group: Builtin (local) administrator
|
||||||
@@ -505,69 +507,8 @@ bool initialize_com_security_policy_for_webview()
|
|||||||
L"(A;;0x3;;;S-1-15-3-1310292540-1029022339-4008023048-2190398717-53961996-4257829345-603366646)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Win32WebViewHost package capability
|
L"(A;;0x3;;;S-1-15-3-1310292540-1029022339-4008023048-2190398717-53961996-4257829345-603366646)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Win32WebViewHost package capability
|
||||||
L"S:"
|
L"S:"
|
||||||
L"(ML;;NX;;;LW)"; // Integrity label on No execute up for Low mandatory level
|
L"(ML;;NX;;;LW)"; // Integrity label on No execute up for Low mandatory level
|
||||||
PSECURITY_DESCRIPTOR self_relative_sd{};
|
|
||||||
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(security_descriptor, SDDL_REVISION_1, &self_relative_sd, nullptr))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
on_scope_exit free_relative_sd([&] {
|
const bool should_try_drop_privileges = !initializeCOMSecurity(security_descriptor) && is_process_elevated(false);
|
||||||
LocalFree(self_relative_sd);
|
|
||||||
});
|
|
||||||
|
|
||||||
DWORD absolute_sd_size = 0;
|
|
||||||
DWORD dacl_size = 0;
|
|
||||||
DWORD group_size = 0;
|
|
||||||
DWORD owner_size = 0;
|
|
||||||
DWORD sacl_size = 0;
|
|
||||||
|
|
||||||
if (!MakeAbsoluteSD(self_relative_sd, nullptr, &absolute_sd_size, nullptr, &dacl_size, nullptr, &sacl_size, nullptr, &owner_size, nullptr, &group_size))
|
|
||||||
{
|
|
||||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typed_storage<SECURITY_DESCRIPTOR> absolute_sd{ absolute_sd_size };
|
|
||||||
typed_storage<ACL> dacl{ dacl_size };
|
|
||||||
typed_storage<ACL> sacl{ sacl_size };
|
|
||||||
typed_storage<SID> owner{ owner_size };
|
|
||||||
typed_storage<SID> group{ group_size };
|
|
||||||
|
|
||||||
if (!MakeAbsoluteSD(self_relative_sd,
|
|
||||||
absolute_sd,
|
|
||||||
&absolute_sd_size,
|
|
||||||
dacl,
|
|
||||||
&dacl_size,
|
|
||||||
sacl,
|
|
||||||
&sacl_size,
|
|
||||||
owner,
|
|
||||||
&owner_size,
|
|
||||||
group,
|
|
||||||
&group_size))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return !FAILED(CoInitializeSecurity(
|
|
||||||
absolute_sd,
|
|
||||||
-1,
|
|
||||||
nullptr,
|
|
||||||
nullptr,
|
|
||||||
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
|
|
||||||
RPC_C_IMP_LEVEL_IDENTIFY,
|
|
||||||
nullptr,
|
|
||||||
EOAC_DYNAMIC_CLOAKING | EOAC_DISABLE_AAA,
|
|
||||||
nullptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
|
|
||||||
{
|
|
||||||
Trace::RegisterProvider();
|
|
||||||
CoInitialize(nullptr);
|
|
||||||
|
|
||||||
const bool should_try_drop_privileges = !initialize_com_security_policy_for_webview() && is_process_elevated(false);
|
|
||||||
|
|
||||||
if (should_try_drop_privileges)
|
if (should_try_drop_privileges)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user