mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-03 08:00:58 +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 {
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
|
@ -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())
|
||||||
|
@ -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 */
|
||||||
|
@ -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; }
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user