libc: limit fd id allocations to FD_SETSIZE

fd > FD_SETSIZE cannot use 'select' or 'poll' within our libc.
Therefore, we added a bit allocator in order to allocate fd < FD_SETSIZE
(1024).

fixes #3568
This commit is contained in:
Sebastian Sumpf 2019-12-04 15:13:16 +01:00 committed by Christian Helmuth
parent e4255e4c8b
commit 6dae147785
3 changed files with 14 additions and 6 deletions

View File

@ -20,6 +20,7 @@
#include <os/path.h>
#include <base/allocator.h>
#include <base/id_space.h>
#include <util/bit_allocator.h>
#include <util/xml_generator.h>
/* libc includes */
@ -57,9 +58,6 @@ namespace Libc {
bool cloexec = 0; /* for 'fcntl' */
bool modified = false;
File_descriptor(Id_space &id_space, Plugin &plugin, Plugin_context &context)
: _elem(*this, id_space), plugin(&plugin), context(&context) { }
File_descriptor(Id_space &id_space, Plugin &plugin, Plugin_context &context,
Id_space::Id id)
: _elem(*this, id_space, id), plugin(&plugin), context(&context) { }
@ -80,6 +78,8 @@ namespace Libc {
Id_space _id_space;
Genode::Bit_allocator<MAX_NUM_FDS> _id_allocator;
public:
/**

View File

@ -61,10 +61,14 @@ File_descriptor *File_descriptor_allocator::alloc(Plugin *plugin,
Lock::Guard guard(_lock);
bool const any_fd = (libc_fd < 0);
if (any_fd)
return new (_alloc) File_descriptor(_id_space, *plugin, *context);
Id_space::Id id {(unsigned)libc_fd};
if (any_fd) {
id.value = _id_allocator.alloc();
} else {
_id_allocator.alloc_addr(addr_t(libc_fd));
}
Id_space::Id const id {(unsigned)libc_fd};
return new (_alloc) File_descriptor(_id_space, *plugin, *context, id);
}
@ -76,6 +80,7 @@ void File_descriptor_allocator::free(File_descriptor *fdo)
if (fdo->fd_path)
_alloc.free((void *)fdo->fd_path, ::strlen(fdo->fd_path) + 1);
_id_allocator.free(fdo->libc_fd);
destroy(_alloc, fdo);
}

View File

@ -169,6 +169,9 @@ static int selscan(int nfds,
if (out_writefds) FD_ZERO(out_writefds);
if (out_exceptfds) FD_ZERO(out_exceptfds);
if (nfds > FD_SETSIZE)
return Libc::Errno(EINVAL);
for (Plugin *plugin = plugin_registry()->first();
plugin;
plugin = plugin->next()) {