From 3f0dcd63dcc1fe9138a08ccc187441b4e0fbf34a Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Wed, 7 Jul 2021 00:17:22 -0600 Subject: [PATCH] Kernel: Fix TmpFS resize behavior around INT32_MAX for 32-bit systems We need some overflow checks due to the implementation of TmpFS. When size_t is 32 bits and off_t is 64 bits, we might overflow our KBuffer max size and confuse the KBuffer set_size code, causing a VERIFY failure. Make sure that resulting offset + size will fit in a size_t. Another constraint, we make sure that the resulting offset + size will be less than half of the maximum value of a size_t, because we double the KBuffer size each time we resize it. --- Kernel/FileSystem/TmpFS.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Kernel/FileSystem/TmpFS.cpp b/Kernel/FileSystem/TmpFS.cpp index ae6a01f9df..fa32e9a2da 100644 --- a/Kernel/FileSystem/TmpFS.cpp +++ b/Kernel/FileSystem/TmpFS.cpp @@ -159,11 +159,14 @@ KResultOr TmpFSInode::write_bytes(off_t offset, size_t size, const UserO off_t old_size = m_metadata.size; off_t new_size = m_metadata.size; - if (offset + size > (size_t)new_size) + if (static_cast(offset + size) > new_size) new_size = offset + size; + if (static_cast(new_size) > (NumericLimits::max() / 2)) // on 32-bit, size_t might be 32 bits while off_t is 64 bits + return ENOMEM; // we won't be able to resize to this capacity + if (new_size > old_size) { - if (m_content && m_content->capacity() >= (size_t)new_size) { + if (m_content && static_cast(m_content->capacity()) >= new_size) { m_content->set_size(new_size); } else { // Grow the content buffer 2x the new sizeto accommodate repeating write() calls.