diff options
7 files changed, 165 insertions, 16 deletions
diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index dc30ebd4066..84e35ba2264 100644 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -1115,14 +1115,13 @@ ProcessMonitor::AttachOpThread(void *arg) { AttachArgs *args = static_cast<AttachArgs*>(arg); - if (!Attach(args)) - return NULL; + Attach(args); ServeOperation(args); return NULL; } -bool +void ProcessMonitor::Attach(AttachArgs *args) { lldb::pid_t pid = args->m_pid; @@ -1134,27 +1133,24 @@ ProcessMonitor::Attach(AttachArgs *args) { args->m_error.SetErrorToGenericError(); args->m_error.SetErrorString("Attaching to process 1 is not allowed."); - goto FINISH; + return; } // Attach to the requested process. if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0) { args->m_error.SetErrorToErrno(); - goto FINISH; + return; } int status; if ((status = waitpid(pid, NULL, 0)) < 0) { args->m_error.SetErrorToErrno(); - goto FINISH; + return; } process.SendMessage(ProcessMessage::Attach(pid)); - -FINISH: - return args->m_error.Success(); } size_t diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h index 68bf2f80051..935fd85ed37 100644 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h +++ b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h @@ -290,7 +290,7 @@ private: static void * AttachOpThread(void *args); - static bool + static void Attach(AttachArgs *args); static void diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp index 702ff800394..0e5ab5a8d8b 100644 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -341,6 +341,11 @@ ProcessPOSIX::DoDestroy() { assert(m_monitor); m_exit_now = true; + if (GetID() == LLDB_INVALID_PROCESS_ID) + { + error.SetErrorString("invalid process id"); + return error; + } if (!m_monitor->Kill()) { error.SetErrorToErrno(); diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index f5650112f4d..3b50799eec6 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -3397,14 +3397,13 @@ Process::Attach (ProcessAttachInfo &attach_info) else { if (GetID() != LLDB_INVALID_PROCESS_ID) - { SetID (LLDB_INVALID_PROCESS_ID); - const char *error_string = error.AsCString(); - if (error_string == NULL) - error_string = "attach failed"; - SetExitStatus(-1, error_string); - } + const char *error_string = error.AsCString(); + if (error_string == NULL) + error_string = "attach failed"; + + SetExitStatus(-1, error_string); } } } diff --git a/lldb/test/functionalities/process_attach/attach_denied/Makefile b/lldb/test/functionalities/process_attach/attach_denied/Makefile new file mode 100644 index 00000000000..87600bbccf9 --- /dev/null +++ b/lldb/test/functionalities/process_attach/attach_denied/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +EXE := AttachDenied + +include $(LEVEL)/Makefile.rules diff --git a/lldb/test/functionalities/process_attach/attach_denied/TestAttachDenied.py b/lldb/test/functionalities/process_attach/attach_denied/TestAttachDenied.py new file mode 100644 index 00000000000..130748137bf --- /dev/null +++ b/lldb/test/functionalities/process_attach/attach_denied/TestAttachDenied.py @@ -0,0 +1,49 @@ +""" +Test denied process attach. +""" + +import os +import shutil +import tempfile +import unittest2 +import lldb +from lldbtest import * + +exe_name = 'AttachDenied' # Must match Makefile + +class AttachDeniedTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfWindows + def test_attach_to_process_by_id_denied(self): + """Test attach by process id denied""" + + self.buildDefault() + exe = os.path.join(os.getcwd(), exe_name) + + temp_dir = tempfile.mkdtemp() + self.addTearDownHook(lambda: shutil.rmtree(temp_dir)) + + # Use named pipe as a synchronization point between test and inferior. + pid_pipe_path = os.path.join(temp_dir, "pid_pipe") + os.mkfifo(pid_pipe_path) + + # Spawn a new process + popen = self.spawnSubprocess(exe, [pid_pipe_path]) + self.addTearDownHook(self.cleanupSubprocesses) + + pid_pipe = open(pid_pipe_path, 'r') + self.addTearDownHook(lambda: pid_pipe.close()) + pid = pid_pipe.read() + + self.expect('process attach -p ' + pid, + startstr = 'error: attach failed:', + error = True) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/functionalities/process_attach/attach_denied/main.cpp b/lldb/test/functionalities/process_attach/attach_denied/main.cpp new file mode 100644 index 00000000000..0fc99f18bcd --- /dev/null +++ b/lldb/test/functionalities/process_attach/attach_denied/main.cpp @@ -0,0 +1,93 @@ +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/ptrace.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#if defined(PTRACE_ATTACH) +#define ATTACH_REQUEST PTRACE_ATTACH +#define DETACH_REQUEST PTRACE_DETACH +#elif defined(PT_ATTACH) +#define ATTACH_REQUEST PT_ATTACH +#define DETACH_REQUEST PT_DETACH +#else +#error "Unsupported platform" +#endif + +bool writePid (const char* file_name, const pid_t pid) +{ + int fd = open (file_name, O_WRONLY); + if (fd == -1) + { + fprintf (stderr, "open(%s) failed: %s\n", file_name, strerror (errno)); + return false; + } + char buffer[64]; + snprintf (buffer, sizeof(buffer), "%ld", (long)pid); + + bool res = true; + if (write (fd, buffer, strlen (buffer)) == -1) + { + fprintf (stderr, "write(%s) failed: %s\n", buffer, strerror (errno)); + res = false; + } + close (fd); + return res; +} + +void sigterm_handler (int) +{ +} + +int main (int argc, char const *argv[]) +{ + if (argc < 2) + { + fprintf (stderr, "invalid number of command line arguments\n"); + return 1; + } + + const pid_t pid = fork (); + if (pid == -1) + { + fprintf (stderr, "fork failed: %s\n", strerror (errno)); + return 1; + } + + if (pid > 0) + { + // Make pause call to return when SIGTERM is received. + signal (SIGTERM, sigterm_handler); + if (ptrace (ATTACH_REQUEST, pid, NULL, 0) == -1) + { + fprintf (stderr, "ptrace(ATTACH) failed: %s\n", strerror (errno)); + } + else + { + if (writePid (argv[1], pid)) + pause (); // Waiting for the debugger trying attach to the child. + + if (ptrace (DETACH_REQUEST, pid, NULL, 0) != 0) + fprintf (stderr, "ptrace(DETACH) failed: %s\n", strerror (errno)); + } + + kill (pid, SIGTERM); + int status = 0; + if (waitpid (pid, &status, 0) == -1) + fprintf (stderr, "waitpid failed: %s\n", strerror (errno)); + } + else + { + // child inferior. + pause (); + } + + printf ("Exiting now\n"); + return 0; +} |