diff options
author | Andreas Kling <kling@serenityos.org> | 2021-02-03 10:54:35 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-02-03 10:54:35 +0100 |
commit | e1236dac3e84bd37a74ce333b706436103ecb7f5 (patch) | |
tree | 502e1d15ed6500f42244724f428caddf0217c2f3 | |
parent | 9f05044c50d7c8931037a499c36fde108e6e317c (diff) | |
download | serenity-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.cpp | 12 |
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()) |