summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-02-03 10:54:35 +0100
committerAndreas Kling <kling@serenityos.org>2021-02-03 10:54:35 +0100
commite1236dac3e84bd37a74ce333b706436103ecb7f5 (patch)
tree502e1d15ed6500f42244724f428caddf0217c2f3
parent9f05044c50d7c8931037a499c36fde108e6e317c (diff)
downloadserenity-e1236dac3e84bd37a74ce333b706436103ecb7f5.zip
Kernel: Check for off_t overflow in FileDescription::read/write
We were checking for size_t (unsigned) overflow but the current offset is actually stored as off_t (signed). Fix this, and also fail with EOVERFLOW correctly.
-rw-r--r--Kernel/FileSystem/FileDescription.cpp12
1 files changed, 4 insertions, 8 deletions
diff --git a/Kernel/FileSystem/FileDescription.cpp b/Kernel/FileSystem/FileDescription.cpp
index 6757be97ad..762411d2be 100644
--- a/Kernel/FileSystem/FileDescription.cpp
+++ b/Kernel/FileSystem/FileDescription.cpp
@@ -165,10 +165,8 @@ off_t FileDescription::seek(off_t offset, int whence)
KResultOr<size_t> FileDescription::read(UserOrKernelBuffer& buffer, size_t count)
{
LOCKER(m_lock);
- Checked<size_t> new_offset = m_current_offset;
- new_offset += count;
- if (new_offset.has_overflow())
- return -EOVERFLOW;
+ if (Checked<off_t>::addition_would_overflow(m_current_offset, count))
+ return EOVERFLOW;
auto nread_or_error = m_file->read(*this, offset(), buffer, count);
if (!nread_or_error.is_error()) {
if (m_file->is_seekable())
@@ -181,10 +179,8 @@ KResultOr<size_t> FileDescription::read(UserOrKernelBuffer& buffer, size_t count
KResultOr<size_t> FileDescription::write(const UserOrKernelBuffer& data, size_t size)
{
LOCKER(m_lock);
- Checked<size_t> new_offset = m_current_offset;
- new_offset += size;
- if (new_offset.has_overflow())
- return -EOVERFLOW;
+ if (Checked<off_t>::addition_would_overflow(m_current_offset, size))
+ return EOVERFLOW;
auto nwritten_or_error = m_file->write(*this, offset(), data, size);
if (!nwritten_or_error.is_error()) {
if (m_file->is_seekable())