noux: close files marked with the 'close_on_execve' flag on 'execve()'

Fixes #2660
This commit is contained in:
Christian Prochaska 2018-01-30 16:39:41 +01:00 committed by Norman Feske
parent c7d1a9e270
commit 584aaec2a5
6 changed files with 46 additions and 23 deletions

View File

@ -155,7 +155,8 @@ struct Noux::Sysio
enum Fcntl_cmd { enum Fcntl_cmd {
FCNTL_CMD_GET_FILE_STATUS_FLAGS, FCNTL_CMD_GET_FILE_STATUS_FLAGS,
FCNTL_CMD_SET_FILE_STATUS_FLAGS, FCNTL_CMD_SET_FILE_STATUS_FLAGS,
FCNTL_CMD_SET_FD_FLAGS FCNTL_CMD_SET_FD_FLAGS,
FCNTL_CMD_GET_FD_FLAGS
}; };
/** /**

View File

@ -1595,14 +1595,8 @@ namespace {
} }
case F_GETFD: case F_GETFD:
/* sysio()->fcntl_in.cmd = Noux::Sysio::FCNTL_CMD_GET_FD_FLAGS;
* Normally, we would return the file-descriptor flags. break;
*
* XXX: FD_CLOEXEC not yet supported
*/
if (verbose)
warning("fcntl(F_GETFD) not implemented, returning 0");
return 0;
case F_SETFD: case F_SETFD:
sysio()->fcntl_in.cmd = Noux::Sysio::FCNTL_CMD_SET_FD_FLAGS; sysio()->fcntl_in.cmd = Noux::Sysio::FCNTL_CMD_SET_FD_FLAGS;

View File

@ -243,11 +243,15 @@ class Noux::Child : public Rpc_object<Session>,
/** /**
* Let specified child inherit our file descriptors * Let specified child inherit our file descriptors
*/ */
void _assign_io_channels_to(Child *child) void _assign_io_channels_to(Child *child, bool skip_when_close_on_execve_set)
{ {
for (int fd = 0; fd < MAX_FILE_DESCRIPTORS; fd++) for (int fd = 0; fd < MAX_FILE_DESCRIPTORS; fd++)
if (fd_in_use(fd)) if (fd_in_use(fd)) {
if (skip_when_close_on_execve_set && close_fd_on_execve(fd))
continue;
child->add_io_channel(io_channel_by_fd(fd), fd); child->add_io_channel(io_channel_by_fd(fd), fd);
child->close_fd_on_execve(fd, close_fd_on_execve(fd));
}
} }
/** /**
@ -536,7 +540,7 @@ class Noux::Child : public Rpc_object<Session>,
false, false,
_destruct_queue); _destruct_queue);
_assign_io_channels_to(child); _assign_io_channels_to(child, true);
/* move the signal queue */ /* move the signal queue */
while (!_pending_signals.empty()) while (!_pending_signals.empty())

View File

@ -30,6 +30,7 @@ class Noux::File_descriptor_registry
struct { struct {
bool allocated; bool allocated;
bool close_on_execve;
Shared_pointer<Io_channel> io_channel; Shared_pointer<Io_channel> io_channel;
} _fds[MAX_FILE_DESCRIPTORS]; } _fds[MAX_FILE_DESCRIPTORS];
@ -51,14 +52,16 @@ class Noux::File_descriptor_registry
void _assign_fd(int fd, Shared_pointer<Io_channel> &io_channel) void _assign_fd(int fd, Shared_pointer<Io_channel> &io_channel)
{ {
_fds[fd].io_channel = io_channel; _fds[fd].io_channel = io_channel;
_fds[fd].allocated = true; _fds[fd].allocated = true;
_fds[fd].close_on_execve = false;
} }
void _reset_fd(int fd) void _reset_fd(int fd)
{ {
_fds[fd].io_channel = Shared_pointer<Io_channel>(); _fds[fd].io_channel = Shared_pointer<Io_channel>();
_fds[fd].allocated = false; _fds[fd].allocated = false;
_fds[fd].close_on_execve = false;
} }
public: public:
@ -110,6 +113,24 @@ class Noux::File_descriptor_registry
return _fds[fd].io_channel; return _fds[fd].io_channel;
} }
void close_fd_on_execve(int fd, bool close_on_execve)
{
if (!_valid_fd(fd))
error("file descriptor ", fd, " is out of range");
else
_fds[fd].close_on_execve = close_on_execve;
}
bool close_fd_on_execve(int fd)
{
if (!_valid_fd(fd)) {
error("file descriptor ", fd, " is out of range");
return false;
}
return _fds[fd].close_on_execve;
}
virtual void flush() virtual void flush()
{ {
/* close all file descriptors */ /* close all file descriptors */

View File

@ -68,10 +68,6 @@ class Noux::Io_channel : public Reference_counter
public: public:
bool close_on_execve;
Io_channel() : close_on_execve(false) { }
virtual ~Io_channel() { } virtual ~Io_channel() { }
virtual Io_channel_backend *backend() { return nullptr; } virtual Io_channel_backend *backend() { return nullptr; }

View File

@ -171,8 +171,15 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
if (_sysio.fcntl_in.cmd == Sysio::FCNTL_CMD_SET_FD_FLAGS) { if (_sysio.fcntl_in.cmd == Sysio::FCNTL_CMD_SET_FD_FLAGS) {
/* we assume that there is only the close-on-execve flag */ /* we assume that there is only the close-on-execve flag */
_lookup_channel(_sysio.fcntl_in.fd)->close_on_execve = close_fd_on_execve(_sysio.fcntl_in.fd, !!_sysio.fcntl_in.long_arg);
!!_sysio.fcntl_in.long_arg; result = true;
break;
}
if (_sysio.fcntl_in.cmd == Sysio::FCNTL_CMD_GET_FD_FLAGS) {
/* we assume that there is only the close-on-execve flag */
_sysio.fcntl_out.result = close_fd_on_execve(_sysio.fcntl_in.fd);
result = true; result = true;
break; break;
} }
@ -556,7 +563,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
Family_member::insert(child); Family_member::insert(child);
_assign_io_channels_to(child); _assign_io_channels_to(child, false);
/* copy our address space into the new child */ /* copy our address space into the new child */
try { try {