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
This commit is contained in:
Carsten Haitzler 2017-09-23 22:44:17 +09:00
parent 17507bab43
commit d136961e3e
2 changed files with 54 additions and 19 deletions

View File

@ -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)

View File

@ -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)
{