Index: source/Plugins/Process/POSIX/ProcessPOSIX.cpp =================================================================== --- source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -340,6 +340,11 @@ { 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(); Index: source/Target/Process.cpp =================================================================== --- source/Target/Process.cpp +++ source/Target/Process.cpp @@ -3397,14 +3397,13 @@ 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); } } } Index: test/functionalities/process_attach/attach_denied/Makefile =================================================================== --- /dev/null +++ test/functionalities/process_attach/attach_denied/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +EXE := AttachDenied + +include $(LEVEL)/Makefile.rules Index: test/functionalities/process_attach/attach_denied/TestAttachDenied.py =================================================================== --- /dev/null +++ test/functionalities/process_attach/attach_denied/TestAttachDenied.py @@ -0,0 +1,51 @@ +""" +Test denied process attach. +""" + +import os +import shutil +import sys +import tempfile +import unittest2 +import lldb +from lldbtest import * + +exe_name = 'AttachDenied' # Must match Makefile + +class AttachDeniedTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @unittest2.skipUnless(sys.platform.startswith("darwin") or sys.platform.startswith("linux"), + "requires Darwin or Linux") + 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. + pipe_path = os.path.join(temp_dir, "attach_denied_pipe") + os.mkfifo(pipe_path) + + # Spawn a new process + popen = self.spawnSubprocess(exe, [pipe_path]) + self.addTearDownHook(self.cleanupSubprocesses) + + sync_pipe = open(pipe_path, 'r') + self.addTearDownHook(lambda: sync_pipe.close()) + sync_pipe.read() + + self.expect('process attach -p ' + str(popen.pid), + startstr = 'error: attach failed:', + error = True) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Index: test/functionalities/process_attach/attach_denied/main.c =================================================================== --- /dev/null +++ test/functionalities/process_attach/attach_denied/main.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include + +#include +#include + +#if defined(__linux__) +#include +#elif defined(__APPLE__) +#include +#endif + +int main(int argc, char const *argv[]) +{ +#if defined(__linux__) +#if defined(PR_SET_DUMPABLE) + if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1) + { + char* err_msg = strerror(errno); + fprintf(stderr, "prctl(PR_SET_DUMPABLE) failed: %s\n", err_msg); + return -1; + } +#endif +#elif defined(__APPLE__) + if (ptrace(PT_DENY_ATTACH, 0, NULL, 0) == -1) + { + char* err_msg = strerror(errno); + fprintf(stderr, "ptrace(PT_DENY_ATTACH) failed: %s\n", err_msg); + return -1; + } +#else +#error "Unsupported platform" +#endif + + if (argc < 2) + { + fprintf(stderr, "invalid number of command line arguments\n"); + return -1; + } + + int fd = 0; + fd = open(argv[1], O_WRONLY); + if (fd == -1) + { + char* err_msg = strerror(errno); + fprintf(stderr, "open(%s) failed: %s\n", argv[1], err_msg); + } + + const char* msg = "1"; + if (write(fd, msg, strlen(msg)) == -1) + { + char* err_msg = strerror(errno); + fprintf(stderr, "write(%s) failed: %s\n", msg, err_msg); + } + close(fd); + + // Waiting to be attempted to attach by the debugger. + sleep(30); + + printf("Exiting now\n"); + return 0; +}