mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-16 07:27:35 +00:00
noux: close files marked with the 'close_on_execve' flag on 'execve()'
Fixes #2660
This commit is contained in:
parent
c7d1a9e270
commit
584aaec2a5
@ -155,7 +155,8 @@ struct Noux::Sysio
|
||||
enum Fcntl_cmd {
|
||||
FCNTL_CMD_GET_FILE_STATUS_FLAGS,
|
||||
FCNTL_CMD_SET_FILE_STATUS_FLAGS,
|
||||
FCNTL_CMD_SET_FD_FLAGS
|
||||
FCNTL_CMD_SET_FD_FLAGS,
|
||||
FCNTL_CMD_GET_FD_FLAGS
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1595,14 +1595,8 @@ namespace {
|
||||
}
|
||||
|
||||
case F_GETFD:
|
||||
/*
|
||||
* Normally, we would return the file-descriptor flags.
|
||||
*
|
||||
* XXX: FD_CLOEXEC not yet supported
|
||||
*/
|
||||
if (verbose)
|
||||
warning("fcntl(F_GETFD) not implemented, returning 0");
|
||||
return 0;
|
||||
sysio()->fcntl_in.cmd = Noux::Sysio::FCNTL_CMD_GET_FD_FLAGS;
|
||||
break;
|
||||
|
||||
case F_SETFD:
|
||||
sysio()->fcntl_in.cmd = Noux::Sysio::FCNTL_CMD_SET_FD_FLAGS;
|
||||
|
@ -243,11 +243,15 @@ class Noux::Child : public Rpc_object<Session>,
|
||||
/**
|
||||
* 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++)
|
||||
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->close_fd_on_execve(fd, close_fd_on_execve(fd));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -536,7 +540,7 @@ class Noux::Child : public Rpc_object<Session>,
|
||||
false,
|
||||
_destruct_queue);
|
||||
|
||||
_assign_io_channels_to(child);
|
||||
_assign_io_channels_to(child, true);
|
||||
|
||||
/* move the signal queue */
|
||||
while (!_pending_signals.empty())
|
||||
|
@ -30,6 +30,7 @@ class Noux::File_descriptor_registry
|
||||
|
||||
struct {
|
||||
bool allocated;
|
||||
bool close_on_execve;
|
||||
Shared_pointer<Io_channel> io_channel;
|
||||
} _fds[MAX_FILE_DESCRIPTORS];
|
||||
|
||||
@ -51,14 +52,16 @@ class Noux::File_descriptor_registry
|
||||
|
||||
void _assign_fd(int fd, Shared_pointer<Io_channel> &io_channel)
|
||||
{
|
||||
_fds[fd].io_channel = io_channel;
|
||||
_fds[fd].allocated = true;
|
||||
_fds[fd].io_channel = io_channel;
|
||||
_fds[fd].allocated = true;
|
||||
_fds[fd].close_on_execve = false;
|
||||
}
|
||||
|
||||
void _reset_fd(int fd)
|
||||
{
|
||||
_fds[fd].io_channel = Shared_pointer<Io_channel>();
|
||||
_fds[fd].allocated = false;
|
||||
_fds[fd].io_channel = Shared_pointer<Io_channel>();
|
||||
_fds[fd].allocated = false;
|
||||
_fds[fd].close_on_execve = false;
|
||||
}
|
||||
|
||||
public:
|
||||
@ -110,6 +113,24 @@ class Noux::File_descriptor_registry
|
||||
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()
|
||||
{
|
||||
/* close all file descriptors */
|
||||
|
@ -68,10 +68,6 @@ class Noux::Io_channel : public Reference_counter
|
||||
|
||||
public:
|
||||
|
||||
bool close_on_execve;
|
||||
|
||||
Io_channel() : close_on_execve(false) { }
|
||||
|
||||
virtual ~Io_channel() { }
|
||||
|
||||
virtual Io_channel_backend *backend() { return nullptr; }
|
||||
|
@ -171,8 +171,15 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
if (_sysio.fcntl_in.cmd == Sysio::FCNTL_CMD_SET_FD_FLAGS) {
|
||||
|
||||
/* we assume that there is only the close-on-execve flag */
|
||||
_lookup_channel(_sysio.fcntl_in.fd)->close_on_execve =
|
||||
!!_sysio.fcntl_in.long_arg;
|
||||
close_fd_on_execve(_sysio.fcntl_in.fd, !!_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;
|
||||
break;
|
||||
}
|
||||
@ -556,7 +563,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
|
||||
Family_member::insert(child);
|
||||
|
||||
_assign_io_channels_to(child);
|
||||
_assign_io_channels_to(child, false);
|
||||
|
||||
/* copy our address space into the new child */
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user