mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Merge pull request #344 from rockihack/windows-dacl
Prevent memory dumps on windows.
This commit is contained in:
commit
cdce9e27fb
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
|
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
|
||||||
|
* Copyright (C) 2017 Lennart Glauer <mail@lennart-glauer.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -26,7 +27,8 @@
|
|||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include <windows.h> // for Sleep(), SetDllDirectoryA() and SetSearchPathMode()
|
#include <windows.h> // for Sleep(), SetDllDirectoryA(), SetSearchPathMode(), ...
|
||||||
|
#include <aclapi.h> // for SetSecurityInfo()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
@ -226,6 +228,10 @@ void disableCoreDumps()
|
|||||||
success = success && (ptrace(PT_DENY_ATTACH, 0, 0, 0) == 0);
|
success = success && (ptrace(PT_DENY_ATTACH, 0, 0, 0) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
success = success && createWindowsDACL();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
qWarning("Unable to disable core dumps.");
|
qWarning("Unable to disable core dumps.");
|
||||||
}
|
}
|
||||||
@ -240,4 +246,114 @@ void setupSearchPaths()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// This function grants the user associated with the process token minimal access rights and
|
||||||
|
// denies everything else on Windows. This includes PROCESS_QUERY_INFORMATION and
|
||||||
|
// PROCESS_VM_READ access rights that are required for MiniDumpWriteDump() or ReadProcessMemory().
|
||||||
|
// We do this using a discretionary access control list (DACL). Effectively this prevents
|
||||||
|
// crash dumps and disallows other processes from accessing our memory. This works as long
|
||||||
|
// as you do not have admin privileges, since then you are able to grant yourself the
|
||||||
|
// SeDebugPrivilege or SeTakeOwnershipPrivilege and circumvent the DACL.
|
||||||
|
//
|
||||||
|
bool createWindowsDACL()
|
||||||
|
{
|
||||||
|
bool bSuccess = false;
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// Process token and user
|
||||||
|
HANDLE hToken = nullptr;
|
||||||
|
PTOKEN_USER pTokenUser = nullptr;
|
||||||
|
DWORD cbBufferSize = 0;
|
||||||
|
|
||||||
|
// Access control list
|
||||||
|
PACL pACL = nullptr;
|
||||||
|
DWORD cbACL = 0;
|
||||||
|
|
||||||
|
// Open the access token associated with the calling process
|
||||||
|
if (!OpenProcessToken(
|
||||||
|
GetCurrentProcess(),
|
||||||
|
TOKEN_QUERY,
|
||||||
|
&hToken
|
||||||
|
)) {
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the token information in a TOKEN_USER structure
|
||||||
|
GetTokenInformation(
|
||||||
|
hToken,
|
||||||
|
TokenUser,
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
&cbBufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
pTokenUser = static_cast<PTOKEN_USER>(HeapAlloc(GetProcessHeap(), 0, cbBufferSize));
|
||||||
|
if (pTokenUser == nullptr) {
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(
|
||||||
|
hToken,
|
||||||
|
TokenUser,
|
||||||
|
pTokenUser,
|
||||||
|
cbBufferSize,
|
||||||
|
&cbBufferSize
|
||||||
|
)) {
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsValidSid(pTokenUser->User.Sid)) {
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the amount of memory that must be allocated for the DACL
|
||||||
|
cbACL = sizeof(ACL)
|
||||||
|
+ sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pTokenUser->User.Sid);
|
||||||
|
|
||||||
|
// Create and initialize an ACL
|
||||||
|
pACL = static_cast<PACL>(HeapAlloc(GetProcessHeap(), 0, cbACL));
|
||||||
|
if (pACL == nullptr) {
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) {
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add allowed access control entries, everything else is denied
|
||||||
|
if (!AddAccessAllowedAce(
|
||||||
|
pACL,
|
||||||
|
ACL_REVISION,
|
||||||
|
SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE, // same as protected process
|
||||||
|
pTokenUser->User.Sid // pointer to the trustee's SID
|
||||||
|
)) {
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set discretionary access control list
|
||||||
|
bSuccess = ERROR_SUCCESS == SetSecurityInfo(
|
||||||
|
GetCurrentProcess(), // object handle
|
||||||
|
SE_KERNEL_OBJECT, // type of object
|
||||||
|
DACL_SECURITY_INFORMATION, // change only the objects DACL
|
||||||
|
nullptr, nullptr, // do not change owner or group
|
||||||
|
pACL, // DACL specified
|
||||||
|
nullptr // do not change SACL
|
||||||
|
);
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
|
||||||
|
if (pACL != nullptr) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, pACL);
|
||||||
|
}
|
||||||
|
if (pTokenUser != nullptr) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, pTokenUser);
|
||||||
|
}
|
||||||
|
if (hToken != nullptr) {
|
||||||
|
CloseHandle(hToken);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return bSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Tools
|
} // namespace Tools
|
||||||
|
@ -41,6 +41,7 @@ void sleep(int ms);
|
|||||||
void wait(int ms);
|
void wait(int ms);
|
||||||
void disableCoreDumps();
|
void disableCoreDumps();
|
||||||
void setupSearchPaths();
|
void setupSearchPaths();
|
||||||
|
bool createWindowsDACL();
|
||||||
|
|
||||||
template <typename RandomAccessIterator, typename T>
|
template <typename RandomAccessIterator, typename T>
|
||||||
RandomAccessIterator binaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T& value)
|
RandomAccessIterator binaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T& value)
|
||||||
|
Loading…
Reference in New Issue
Block a user