From 6dae147785cfd0fd7293eedb5c3a5754c9520bba Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Wed, 4 Dec 2019 15:13:16 +0100 Subject: [PATCH] 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 --- repos/libports/include/libc-plugin/fd_alloc.h | 6 +++--- repos/libports/src/lib/libc/fd_alloc.cc | 11 ++++++++--- repos/libports/src/lib/libc/select.cc | 3 +++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/repos/libports/include/libc-plugin/fd_alloc.h b/repos/libports/include/libc-plugin/fd_alloc.h index e03dfa739..dabf3572b 100644 --- a/repos/libports/include/libc-plugin/fd_alloc.h +++ b/repos/libports/include/libc-plugin/fd_alloc.h @@ -20,6 +20,7 @@ #include #include #include +#include #include /* 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 _id_allocator; + public: /** diff --git a/repos/libports/src/lib/libc/fd_alloc.cc b/repos/libports/src/lib/libc/fd_alloc.cc index 95eb4202f..b003f75dd 100644 --- a/repos/libports/src/lib/libc/fd_alloc.cc +++ b/repos/libports/src/lib/libc/fd_alloc.cc @@ -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); } diff --git a/repos/libports/src/lib/libc/select.cc b/repos/libports/src/lib/libc/select.cc index eca9677a4..0c7d65335 100644 --- a/repos/libports/src/lib/libc/select.cc +++ b/repos/libports/src/lib/libc/select.cc @@ -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()) {