From f9925ee38bc998d27e5d90bda6c4e9f25abc521e Mon Sep 17 00:00:00 2001 From: Daniel Trnka Date: Tue, 14 Mar 2017 15:26:40 +0100 Subject: [PATCH 1/3] _createChild: try to close descriptors in /proc/self/fd or /dev/fd --- ptrace/debugger/child.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/ptrace/debugger/child.py b/ptrace/debugger/child.py index 1791a04..175b137 100644 --- a/ptrace/debugger/child.py +++ b/ptrace/debugger/child.py @@ -4,7 +4,8 @@ from os import ( fork, execvp, execvpe, waitpid, close, dup2, pipe, - read, write, devnull, sysconf) + read, write, devnull, sysconf, listdir) +from os.path import isdir from sys import exc_info from traceback import format_exception from ptrace.os_tools import RUNNING_WINDOWS @@ -87,6 +88,27 @@ def _createParent(pid, errpipe_read): raise child_exception +def _closeFdsExcept(fds, ignore_fds): + for fd in fds: + if fd not in ignore_fds: + try: + close(fd) + except OSError: + pass + + +def _closeFds(ignore_fds): + for path in ['/proc/self/fd', '/dev/fd']: + try: + if isdir(path): + _closeFdsExcept([int(i) for i in listdir(path)], ignore_fds) + return + except OSError: + pass + + _closeFdsExcept(range(0, MAXFD), ignore_fds) + + def _createChild(arguments, no_stdout, env, errpipe_write): # Child code try: @@ -95,13 +117,8 @@ def _createChild(arguments, no_stdout, env, errpipe_write): raise ChildError(str(err)) # Close all files except 0, 1, 2 and errpipe_write - for fd in range(3, MAXFD): - if fd == errpipe_write: - continue - try: - close(fd) - except OSError: - pass + _closeFds([0, 1, 2, errpipe_write]) + try: _execChild(arguments, no_stdout, env) except: From e122381f5ec29eed2ab9daf27d240c25208a97fd Mon Sep 17 00:00:00 2001 From: Daniel Trnka Date: Thu, 16 Mar 2017 17:08:17 +0100 Subject: [PATCH 2/3] child.py close: check if system has /proc, check that FreeBSD has /dev/fd mounted --- ptrace/debugger/child.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/ptrace/debugger/child.py b/ptrace/debugger/child.py index 175b137..510ba29 100644 --- a/ptrace/debugger/child.py +++ b/ptrace/debugger/child.py @@ -4,11 +4,11 @@ from os import ( fork, execvp, execvpe, waitpid, close, dup2, pipe, - read, write, devnull, sysconf, listdir) + read, write, devnull, sysconf, listdir, stat) from os.path import isdir from sys import exc_info from traceback import format_exception -from ptrace.os_tools import RUNNING_WINDOWS +from ptrace.os_tools import RUNNING_WINDOWS, RUNNING_FREEBSD, HAS_PROC from ptrace.binding import ptrace_traceme from ptrace import PtraceError from sys import exit @@ -98,17 +98,31 @@ def _closeFdsExcept(fds, ignore_fds): def _closeFds(ignore_fds): - for path in ['/proc/self/fd', '/dev/fd']: + path = None + if HAS_PROC: + path = '/proc/self/fd' + elif _hasDevFd(): + path = '/dev/fd' + + if path: try: - if isdir(path): - _closeFdsExcept([int(i) for i in listdir(path)], ignore_fds) - return + _closeFdsExcept([int(i) for i in listdir(path)], ignore_fds) + return except OSError: pass _closeFdsExcept(range(0, MAXFD), ignore_fds) +def _hasDevFd(): + try: + # have fdescfs if /dev/fd is on different device + # see https://github.com/python/cpython/blob/master/Modules/_posixsubprocess.c + return RUNNING_FREEBSD and stat("/dev/fd/").st_dev != stat("/dev/").st_dev + except OSError: + return False + + def _createChild(arguments, no_stdout, env, errpipe_write): # Child code try: From 7fb604bfeaacea762d75ba239557486dcc48ea63 Mon Sep 17 00:00:00 2001 From: Daniel Trnka Date: Thu, 16 Mar 2017 18:20:05 +0100 Subject: [PATCH 3/3] Removed unused import --- ptrace/debugger/child.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ptrace/debugger/child.py b/ptrace/debugger/child.py index 510ba29..a6c49c6 100644 --- a/ptrace/debugger/child.py +++ b/ptrace/debugger/child.py @@ -5,7 +5,6 @@ fork, execvp, execvpe, waitpid, close, dup2, pipe, read, write, devnull, sysconf, listdir, stat) -from os.path import isdir from sys import exc_info from traceback import format_exception from ptrace.os_tools import RUNNING_WINDOWS, RUNNING_FREEBSD, HAS_PROC