summaryrefslogtreecommitdiff
path: root/gdb/nat/windows-nat.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/nat/windows-nat.c')
-rw-r--r--gdb/nat/windows-nat.c115
1 files changed, 112 insertions, 3 deletions
diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index 8048344752b..e52da16d9ce 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -69,6 +69,10 @@ GenerateConsoleCtrlEvent_ftype *GenerateConsoleCtrlEvent;
typedef HRESULT WINAPI (GetThreadDescription_ftype) (HANDLE, PWSTR *);
static GetThreadDescription_ftype *GetThreadDescription;
+InitializeProcThreadAttributeList_ftype *InitializeProcThreadAttributeList;
+UpdateProcThreadAttribute_ftype *UpdateProcThreadAttribute;
+DeleteProcThreadAttributeList_ftype *DeleteProcThreadAttributeList;
+
/* Note that 'debug_events' must be locally defined in the relevant
functions. */
#define DEBUG_EVENTS(fmt, ...) \
@@ -741,15 +745,104 @@ wait_for_debug_event (DEBUG_EVENT *event, DWORD timeout)
return result;
}
-/* Helper template for the CreateProcess wrappers. */
+/* Flags to pass to UpdateProcThreadAttribute. */
+#define relocate_aslr_flags ((0x2 << 8) | (0x2 << 16))
+
+/* Attribute to pass to UpdateProcThreadAttribute. */
+#define mitigation_policy 0x00020007
+
+/* Pick one of the symbols as a sentinel. */
+#ifdef PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_OFF
+
+static_assert ((PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_OFF
+ | PROCESS_CREATION_MITIGATION_POLICY_BOTTOM_UP_ASLR_ALWAYS_OFF)
+ == relocate_aslr_flags,
+ "check that ASLR flag values are correct");
+
+static_assert (PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY == mitigation_policy,
+ "check that mitigation policy value is correct");
+
+#endif
+
+/* Helper template for the CreateProcess wrappers.
+
+ FUNC is the type of the underlying CreateProcess call. CHAR is the
+ character type to use, and INFO is the "startupinfo" type to use.
+
+ DO_CREATE_PROCESS is the underlying CreateProcess function to use;
+ the remaining arguments are passed to it. */
template<typename FUNC, typename CHAR, typename INFO>
BOOL
create_process_wrapper (FUNC *do_create_process, const CHAR *image,
CHAR *command_line, DWORD flags,
void *environment, const CHAR *cur_dir,
+ bool no_randomization,
INFO *startup_info,
PROCESS_INFORMATION *process_info)
{
+ if (no_randomization && disable_randomization_available ())
+ {
+ static bool tried_and_failed;
+
+ if (!tried_and_failed)
+ {
+ /* Windows 8 is required for the real declaration, but to
+ allow building on earlier versions of Windows, we declare
+ the type locally. */
+ struct gdb_extended_info
+ {
+ INFO StartupInfo;
+ gdb_lpproc_thread_attribute_list lpAttributeList;
+ };
+
+ gdb_extended_info info_ex {};
+
+ if (startup_info != nullptr)
+ info_ex.StartupInfo = *startup_info;
+ info_ex.StartupInfo.cb = sizeof (info_ex);
+ SIZE_T size = 0;
+ /* Ignore the result here. The documentation says the first
+ call always fails, by design. */
+ InitializeProcThreadAttributeList (nullptr, 1, 0, &size);
+ info_ex.lpAttributeList
+ = (PPROC_THREAD_ATTRIBUTE_LIST) alloca (size);
+ InitializeProcThreadAttributeList (info_ex.lpAttributeList,
+ 1, 0, &size);
+
+ gdb::optional<BOOL> return_value;
+ DWORD attr_flags = relocate_aslr_flags;
+ if (!UpdateProcThreadAttribute (info_ex.lpAttributeList, 0,
+ mitigation_policy,
+ &attr_flags,
+ sizeof (attr_flags),
+ nullptr, nullptr))
+ tried_and_failed = true;
+ else
+ {
+ BOOL result = do_create_process (image, command_line,
+ nullptr, nullptr,
+ TRUE,
+ (flags
+ | EXTENDED_STARTUPINFO_PRESENT),
+ environment,
+ cur_dir,
+ (STARTUPINFO *) &info_ex,
+ process_info);
+ if (result)
+ return_value = result;
+ else if (GetLastError () == ERROR_INVALID_PARAMETER)
+ tried_and_failed = true;
+ else
+ return_value = FALSE;
+ }
+
+ DeleteProcThreadAttributeList (info_ex.lpAttributeList);
+
+ if (return_value.has_value ())
+ return *return_value;
+ }
+ }
+
return do_create_process (image,
command_line, /* command line */
nullptr, /* Security */
@@ -767,11 +860,12 @@ create_process_wrapper (FUNC *do_create_process, const CHAR *image,
BOOL
create_process (const char *image, char *command_line, DWORD flags,
void *environment, const char *cur_dir,
+ bool no_randomization,
STARTUPINFOA *startup_info,
PROCESS_INFORMATION *process_info)
{
return create_process_wrapper (CreateProcessA, image, command_line, flags,
- environment, cur_dir,
+ environment, cur_dir, no_randomization,
startup_info, process_info);
}
@@ -782,11 +876,12 @@ create_process (const char *image, char *command_line, DWORD flags,
BOOL
create_process (const wchar_t *image, wchar_t *command_line, DWORD flags,
void *environment, const wchar_t *cur_dir,
+ bool no_randomization,
STARTUPINFOW *startup_info,
PROCESS_INFORMATION *process_info);
{
return create_process_wrapper (CreateProcessW, image, command_line, flags,
- environment, cur_dir,
+ environment, cur_dir, no_randomization,
startup_info, process_info);
}
@@ -827,6 +922,16 @@ bad_GetConsoleFontSize (HANDLE w, DWORD nFont)
/* See windows-nat.h. */
bool
+disable_randomization_available ()
+{
+ return (InitializeProcThreadAttributeList != nullptr
+ && UpdateProcThreadAttribute != nullptr
+ && DeleteProcThreadAttributeList != nullptr);
+}
+
+/* See windows-nat.h. */
+
+bool
initialize_loadable ()
{
bool result = true;
@@ -852,6 +957,10 @@ initialize_loadable ()
#endif
GPA (hm, GenerateConsoleCtrlEvent);
GPA (hm, GetThreadDescription);
+
+ GPA (hm, InitializeProcThreadAttributeList);
+ GPA (hm, UpdateProcThreadAttribute);
+ GPA (hm, DeleteProcThreadAttributeList);
}
/* Set variables to dummy versions of these processes if the function