diff options
author | Todd Fiala <todd.fiala@gmail.com> | 2014-08-17 00:10:50 +0000 |
---|---|---|
committer | Todd Fiala <todd.fiala@gmail.com> | 2014-08-17 00:10:50 +0000 |
commit | 0bce1b67a3074d26c53fc5eb8d8edfa66bcfff77 (patch) | |
tree | fb7586b7f6350deb966cdd6c4f35a110c689e3eb /lldb/source/Plugins | |
parent | 067d4c7c2790b8500a536edcfe8834e8343632ad (diff) | |
download | bcm5719-llvm-0bce1b67a3074d26c53fc5eb8d8edfa66bcfff77.tar.gz bcm5719-llvm-0bce1b67a3074d26c53fc5eb8d8edfa66bcfff77.zip |
Fix Linux to respect ASLR settings when launching processes to debug locally and remotely.
See the following links for details:
http://llvm.org/bugs/show_bug.cgi?id=20658
See http://reviews.llvm.org/D4941
llvm-svn: 215822
Diffstat (limited to 'lldb/source/Plugins')
7 files changed, 94 insertions, 8 deletions
diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index cbafc4ca092..63439b15511 100644 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -807,6 +807,7 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, const char *stdout_path, const char *stderr_path, const char *working_dir, + const lldb_private::ProcessLaunchInfo & /* launch_info */, lldb_private::Error &error) : m_process(static_cast<ProcessFreeBSD *>(process)), m_operation_thread(LLDB_INVALID_HOST_THREAD), diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h index ad888095147..314743b0075 100644 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h +++ b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h @@ -55,6 +55,7 @@ public: const char *stdout_path, const char *stderr_path, const char *working_dir, + const lldb_private::ProcessLaunchInfo &launch_info, lldb_private::Error &error); ProcessMonitor(ProcessPOSIX *process, diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index 6a7e6b89289..9d88bb26535 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -18,6 +18,7 @@ #include <stdint.h> #include <unistd.h> #include <linux/unistd.h> +#include <sys/personality.h> #include <sys/ptrace.h> #include <sys/socket.h> #include <sys/syscall.h> @@ -92,6 +93,7 @@ #define ARCH_GET_GS 0x1004 #endif +#define LLDB_PERSONALITY_GET_CURRENT_SETTINGS 0xffffffff // Support hardware breakpoints in case it has not been defined #ifndef TRAP_HWBKPT @@ -993,7 +995,8 @@ NativeProcessLinux::LaunchArgs::LaunchArgs(NativeProcessLinux *monitor, const char *stdin_path, const char *stdout_path, const char *stderr_path, - const char *working_dir) + const char *working_dir, + const lldb_private::ProcessLaunchInfo &launch_info) : OperationArgs(monitor), m_module(module), m_argv(argv), @@ -1001,7 +1004,10 @@ NativeProcessLinux::LaunchArgs::LaunchArgs(NativeProcessLinux *monitor, m_stdin_path(stdin_path), m_stdout_path(stdout_path), m_stderr_path(stderr_path), - m_working_dir(working_dir) { } + m_working_dir(working_dir), + m_launch_info(launch_info) +{ +} NativeProcessLinux::LaunchArgs::~LaunchArgs() { } @@ -1084,6 +1090,7 @@ NativeProcessLinux::LaunchProcess ( stdout_path, stderr_path, working_dir, + launch_info, error); if (error.Fail ()) @@ -1182,6 +1189,7 @@ NativeProcessLinux::LaunchInferior ( const char *stdout_path, const char *stderr_path, const char *working_dir, + const lldb_private::ProcessLaunchInfo &launch_info, lldb_private::Error &error) { if (module) @@ -1193,7 +1201,7 @@ NativeProcessLinux::LaunchInferior ( new LaunchArgs( this, module, argv, envp, stdin_path, stdout_path, stderr_path, - working_dir)); + working_dir, launch_info)); sem_init(&m_operation_pending, 0, 0); sem_init(&m_operation_done, 0, 0); @@ -1351,6 +1359,10 @@ NativeProcessLinux::LaunchOpThread(void *arg) bool NativeProcessLinux::Launch(LaunchArgs *args) { + assert (args && "null args"); + if (!args) + return false; + NativeProcessLinux *monitor = args->m_monitor; assert (monitor && "monitor is NULL"); if (!monitor) @@ -1462,6 +1474,33 @@ NativeProcessLinux::Launch(LaunchArgs *args) if (0 != ::chdir(working_dir)) exit(eChdirFailed); + // Disable ASLR if requested. + if (args->m_launch_info.GetFlags ().Test (lldb::eLaunchFlagDisableASLR)) + { + const int old_personality = personality (LLDB_PERSONALITY_GET_CURRENT_SETTINGS); + if (old_personality == -1) + { + if (log) + log->Printf ("NativeProcessLinux::%s retrieval of Linux personality () failed: %s. Cannot disable ASLR.", __FUNCTION__, strerror (errno)); + } + else + { + const int new_personality = personality (ADDR_NO_RANDOMIZE | old_personality); + if (new_personality == -1) + { + if (log) + log->Printf ("NativeProcessLinux::%s setting of Linux personality () to disable ASLR failed, ignoring: %s", __FUNCTION__, strerror (errno)); + + } + else + { + if (log) + log->Printf ("NativeProcessLinux::%s disbling ASLR: SUCCESS", __FUNCTION__); + + } + } + } + // Execute. We should never return. execve(argv[0], const_cast<char *const *>(argv), diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h index f72b01bac61..ee71376a3b2 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h @@ -217,7 +217,8 @@ namespace lldb_private const char *stdin_path, const char *stdout_path, const char *stderr_path, - const char *working_dir); + const char *working_dir, + const lldb_private::ProcessLaunchInfo &launch_info); ~LaunchArgs(); @@ -228,6 +229,7 @@ namespace lldb_private const char *m_stdout_path; // Redirect stdout or NULL. const char *m_stderr_path; // Redirect stderr or NULL. const char *m_working_dir; // Working directory or NULL. + const lldb_private::ProcessLaunchInfo &m_launch_info; }; struct AttachArgs : OperationArgs @@ -256,6 +258,7 @@ namespace lldb_private const char *stdout_path, const char *stderr_path, const char *working_dir, + const lldb_private::ProcessLaunchInfo &launch_info, Error &error); /// Attaches to an existing process. Forms the diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp index 9e5f844bd13..42a0aa51f4c 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp @@ -15,6 +15,7 @@ #include <string.h> #include <stdint.h> #include <unistd.h> +#include <sys/personality.h> #include <sys/ptrace.h> #include <sys/socket.h> #include <sys/syscall.h> @@ -60,6 +61,7 @@ #define ARCH_GET_GS 0x1004 #endif +#define LLDB_PERSONALITY_GET_CURRENT_SETTINGS 0xffffffff // Support hardware breakpoints in case it has not been defined #ifndef TRAP_HWBKPT @@ -967,7 +969,8 @@ ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor, const char *stdin_path, const char *stdout_path, const char *stderr_path, - const char *working_dir) + const char *working_dir, + const lldb_private::ProcessLaunchInfo &launch_info) : OperationArgs(monitor), m_module(module), m_argv(argv), @@ -975,7 +978,10 @@ ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor, m_stdin_path(stdin_path), m_stdout_path(stdout_path), m_stderr_path(stderr_path), - m_working_dir(working_dir) { } + m_working_dir(working_dir), + m_launch_info(launch_info) +{ +} ProcessMonitor::LaunchArgs::~LaunchArgs() { } @@ -1007,6 +1013,7 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, const char *stdout_path, const char *stderr_path, const char *working_dir, + const lldb_private::ProcessLaunchInfo &launch_info, lldb_private::Error &error) : m_process(static_cast<ProcessLinux *>(process)), m_operation_thread(LLDB_INVALID_HOST_THREAD), @@ -1017,7 +1024,7 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, { std::unique_ptr<LaunchArgs> args(new LaunchArgs(this, module, argv, envp, stdin_path, stdout_path, stderr_path, - working_dir)); + working_dir, launch_info)); sem_init(&m_operation_pending, 0, 0); sem_init(&m_operation_done, 0, 0); @@ -1145,6 +1152,10 @@ ProcessMonitor::LaunchOpThread(void *arg) bool ProcessMonitor::Launch(LaunchArgs *args) { + assert (args && "null args"); + if (!args) + return false; + ProcessMonitor *monitor = args->m_monitor; ProcessLinux &process = monitor->GetProcess(); const char **argv = args->m_argv; @@ -1219,6 +1230,33 @@ ProcessMonitor::Launch(LaunchArgs *args) if (0 != ::chdir(working_dir)) exit(eChdirFailed); + // Disable ASLR if requested. + if (args->m_launch_info.GetFlags ().Test (lldb::eLaunchFlagDisableASLR)) + { + const int old_personality = personality (LLDB_PERSONALITY_GET_CURRENT_SETTINGS); + if (old_personality == -1) + { + if (log) + log->Printf ("ProcessMonitor::%s retrieval of Linux personality () failed: %s. Cannot disable ASLR.", __FUNCTION__, strerror (errno)); + } + else + { + const int new_personality = personality (ADDR_NO_RANDOMIZE | old_personality); + if (new_personality == -1) + { + if (log) + log->Printf ("ProcessMonitor::%s setting of Linux personality () to disable ASLR failed, ignoring: %s", __FUNCTION__, strerror (errno)); + + } + else + { + if (log) + log->Printf ("ProcessMonitor::%s disbling ASLR: SUCCESS", __FUNCTION__); + + } + } + } + // Execute. We should never return. execve(argv[0], const_cast<char *const *>(argv), diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h index 3e289ff1337..bd3253412a1 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h @@ -55,6 +55,7 @@ public: const char *stdout_path, const char *stderr_path, const char *working_dir, + const lldb_private::ProcessLaunchInfo &launch_info, lldb_private::Error &error); ProcessMonitor(ProcessPOSIX *process, @@ -233,7 +234,8 @@ private: const char *stdin_path, const char *stdout_path, const char *stderr_path, - const char *working_dir); + const char *working_dir, + const lldb_private::ProcessLaunchInfo &launch_info); ~LaunchArgs(); @@ -244,6 +246,7 @@ private: const char *m_stdout_path; // Redirect stdout or NULL. const char *m_stderr_path; // Redirect stderr or NULL. const char *m_working_dir; // Working directory or NULL. + const lldb_private::ProcessLaunchInfo &m_launch_info; }; void diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp index 2ce61e94d85..e96e0b6ae2d 100644 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -241,6 +241,7 @@ ProcessPOSIX::DoLaunch (Module *module, stdout_path, stderr_path, working_dir, + launch_info, error); m_module = module; |