diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 79cf40e494d..900fd69f269 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -1107,13 +1107,16 @@ ssize_t ProcFSInode::read_bytes(off_t offset, ssize_t count, u8* buffer, FileDes } auto& data = generated_data; - ssize_t nread = 0; - if (data.has_value()) { - nread = min(static_cast(data.value().size() - offset), static_cast(count)); - memcpy(buffer, data.value().data() + offset, nread); - if (nread == 0 && description && description->generator_cache()) - description->generator_cache().clear(); - } + if (!data.has_value()) + return 0; + + if ((size_t)offset >= data.value().size()) + return 0; + + ssize_t nread = min(static_cast(data.value().size() - offset), static_cast(count)); + memcpy(buffer, data.value().data() + offset, nread); + if (nread == 0 && description && description->generator_cache()) + description->generator_cache().clear(); return nread; } diff --git a/Userland/test_io.cpp b/Userland/test_io.cpp index d009474f0ae..44f58e2ddc2 100644 --- a/Userland/test_io.cpp +++ b/Userland/test_io.cpp @@ -140,6 +140,22 @@ void test_tmpfs_read_past_end() close(fd); } +void test_procfs_read_past_end() +{ + int fd = open("/proc/uptime", O_RDONLY); + ASSERT(fd >= 0); + + int rc = lseek(fd, 4096, SEEK_SET); + ASSERT(rc == 4096); + + char buffer[16]; + int nread = read(fd, buffer, sizeof(buffer)); + if (nread != 0) { + fprintf(stderr, "Expected 0-length read past end of file in /proc\n"); + } + close(fd); +} + int main(int, char**) { int rc; @@ -160,6 +176,7 @@ int main(int, char**) test_ftruncate_negative(); test_mmap_directory(); test_tmpfs_read_past_end(); + test_procfs_read_past_end(); return 0; }