From d136961e3eeb53fa73a2326dc66c4ccd37b13e75 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Sat, 23 Sep 2017 22:44:17 +0900 Subject: ecore exe - add an "isolate io"f lag for sending io to /dev/null this is useful for security to disallow child processes access to stdio/err of the parent process. @feature --- src/lib/ecore/ecore_exe.eo | 3 +- src/lib/ecore/ecore_exe_posix.c | 70 ++++++++++++++++++++++++++++++----------- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/lib/ecore/ecore_exe.eo b/src/lib/ecore/ecore_exe.eo index 78a1da9e03..100f5b35f3 100644 --- a/src/lib/ecore/ecore_exe.eo +++ b/src/lib/ecore/ecore_exe.eo @@ -35,7 +35,8 @@ enum Ecore.Exe_Flags respawn = 64, [[FIXME: Exe is restarted if it dies]] use_sh = 128, [[Use /bin/sh to run the command.]] not_leader = 256, [[Do not use setsid() to have the executed process be its own session leader]] - term_with_parent = 512 [[Makes child receive SIGTERM when parent dies.]] + term_with_parent = 512, [[Makes child receive SIGTERM when parent dies.]] + isolate_io = 1024, [[Try and isolate stdin/out and err of the process so it isn't shared with the parent.]] } class Ecore.Exe (Efl.Object, Efl.Control) diff --git a/src/lib/ecore/ecore_exe_posix.c b/src/lib/ecore/ecore_exe_posix.c index 2a240a2d01..3cbba20f44 100644 --- a/src/lib/ecore/ecore_exe_posix.c +++ b/src/lib/ecore/ecore_exe_posix.c @@ -317,24 +317,58 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe) #warning "Have support for this" #endif } - /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the - * second pipe if it's open. On the other hand, there was the - * Great FD Leak Scare of '06, so let's be paranoid. */ - if (ok && (flags & ECORE_EXE_PIPE_ERROR)) - { - E_NO_ERRNO(result, close(STDERR_FILENO), ok); - E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok); - } - if (ok && (flags & ECORE_EXE_PIPE_READ)) - { - E_NO_ERRNO(result, close(STDOUT_FILENO), ok); - E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok); - } - if (ok && (flags & ECORE_EXE_PIPE_WRITE)) - { - E_NO_ERRNO(result, close(STDIN_FILENO), ok); - E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok); - } + if (ok && (flags & ECORE_EXE_ISOLATE_IO)) + { + int devnull; + + /* we want to isolatie the stdin/out/err of the process so + * it can't share those of the parent, so close and replace with + * /dev/null */ + devnull = open("/dev/null", O_RDONLY); + if (devnull >= 0) + { + E_NO_ERRNO(result, close(STDIN_FILENO), ok); + E_NO_ERRNO(result, dup2(devnull, STDIN_FILENO), ok); + E_NO_ERRNO(result, close(devnull), ok); + } + + devnull = open("/dev/null", O_WRONLY); + if (devnull >= 0) + { + E_NO_ERRNO(result, close(STDOUT_FILENO), ok); + E_NO_ERRNO(result, dup2(devnull, STDOUT_FILENO), ok); + E_NO_ERRNO(result, close(devnull), ok); + } + + devnull = open("/dev/null", O_WRONLY); + if (devnull >= 0) + { + E_NO_ERRNO(result, close(STDERR_FILENO), ok); + E_NO_ERRNO(result, dup2(devnull, STDERR_FILENO), ok); + E_NO_ERRNO(result, close(devnull), ok); + } + } + else + { + /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the + * second pipe if it's open. On the other hand, there was the + * Great FD Leak Scare of '06, so let's be paranoid. */ + if (ok && (flags & ECORE_EXE_PIPE_ERROR)) + { + E_NO_ERRNO(result, close(STDERR_FILENO), ok); + E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok); + } + if (ok && (flags & ECORE_EXE_PIPE_READ)) + { + E_NO_ERRNO(result, close(STDOUT_FILENO), ok); + E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok); + } + if (ok && (flags & ECORE_EXE_PIPE_WRITE)) + { + E_NO_ERRNO(result, close(STDIN_FILENO), ok); + E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok); + } + } if (ok) { -- cgit v1.2.1