From 0e01729d778dd748336074849f20a7ee9a11cb81 Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Tue, 6 Oct 2020 19:07:52 +0200 Subject: [PATCH] libc: handle file descriptor allocation errors Fixes #3906 --- repos/libports/src/lib/libc/vfs_plugin.cc | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/repos/libports/src/lib/libc/vfs_plugin.cc b/repos/libports/src/lib/libc/vfs_plugin.cc index f3fbd03df4..a7b754b3f4 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.cc +++ b/repos/libports/src/lib/libc/vfs_plugin.cc @@ -287,6 +287,12 @@ Libc::File_descriptor *Libc::Vfs_plugin::open_from_kernel(const char *path, int File_descriptor *fd = file_descriptor_allocator()->alloc(this, vfs_context(handle), libc_fd); + if (!fd) { + handle->close(); + errno = EMFILE; + return nullptr; + } + handle->handler(&_response_handler); fd->flags = flags & O_ACCMODE; @@ -360,6 +366,12 @@ Libc::File_descriptor *Libc::Vfs_plugin::open_from_kernel(const char *path, int File_descriptor *fd = file_descriptor_allocator()->alloc(this, vfs_context(handle), libc_fd); + if (!fd) { + handle->close(); + errno = EMFILE; + return nullptr; + } + handle->handler(&_response_handler); fd->flags = flags & (O_ACCMODE|O_NONBLOCK|O_APPEND); @@ -406,8 +418,6 @@ Libc::File_descriptor *Libc::Vfs_plugin::open(char const *path, int flags) fd = file_descriptor_allocator()->alloc(this, vfs_context(handle), Libc::ANY_FD); - /* FIXME error cleanup code leaks resources! */ - if (!fd) { handle->close(); result_errno = EMFILE; @@ -487,8 +497,6 @@ Libc::File_descriptor *Libc::Vfs_plugin::open(char const *path, int flags) fd = file_descriptor_allocator()->alloc(this, vfs_context(handle), Libc::ANY_FD); - /* FIXME error cleanup code leaks resources! */ - if (!fd) { handle->close(); result_errno = EMFILE; @@ -654,6 +662,12 @@ Libc::File_descriptor *Libc::Vfs_plugin::dup(File_descriptor *fd) File_descriptor * const new_fd = file_descriptor_allocator()->alloc(this, vfs_context(handle)); + if (!new_fd) { + handle->close(); + result_errno = EMFILE; + return Fn::COMPLETE; + } + new_fd->flags = fd->flags; new_fd->path(fd->fd_path);