From 0754471d2dda656b3a81ac61a91f77cde7e891db Mon Sep 17 00:00:00 2001
From: Saagar Jha
Date: Mon, 15 Jun 2020 18:57:48 -0700
Subject: [PATCH] Handle zero-length mmaps correctly
---
emu/memory.h | 3 ++-
fs/real.c | 3 ---
kernel/mmap.c | 1 +
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/emu/memory.h b/emu/memory.h
index 907c664716..675e37a36d 100644
--- a/emu/memory.h
+++ b/emu/memory.h
@@ -45,7 +45,8 @@ void mem_next_page(struct mem *mem, page_t *page);
#define PAGE(addr) ((addr) >> PAGE_BITS)
#define PGOFFSET(addr) ((addr) & (PAGE_SIZE - 1))
typedef dword_t pages_t;
-#define PAGE_ROUND_UP(bytes) (((bytes - 1) / PAGE_SIZE) + 1)
+// bytes MUST be unsigned if you would like this to overflow to zero
+#define PAGE_ROUND_UP(bytes) (PAGE((bytes) + PAGE_SIZE - 1))
#define BYTES_ROUND_DOWN(bytes) (PAGE(bytes) << PAGE_BITS)
#define BYTES_ROUND_UP(bytes) (PAGE_ROUND_UP(bytes) << PAGE_BITS)
diff --git a/fs/real.c b/fs/real.c
index 4d2ed7d203..50a9786e6c 100644
--- a/fs/real.c
+++ b/fs/real.c
@@ -263,9 +263,6 @@ int realfs_poll(struct fd *fd) {
}
int realfs_mmap(struct fd *fd, struct mem *mem, page_t start, pages_t pages, off_t offset, int prot, int flags) {
- if (pages == 0)
- return 0;
-
int mmap_flags = 0;
if (flags & MMAP_PRIVATE) mmap_flags |= MAP_PRIVATE;
if (flags & MMAP_SHARED) mmap_flags |= MAP_SHARED;
diff --git a/kernel/mmap.c b/kernel/mmap.c
index 1f579dcf94..823fd3a5ad 100644
--- a/kernel/mmap.c
+++ b/kernel/mmap.c
@@ -50,6 +50,7 @@ void mm_release(struct mm *mm) {
static addr_t do_mmap(addr_t addr, dword_t len, dword_t prot, dword_t flags, fd_t fd_no, dword_t offset) {
int err;
pages_t pages = PAGE_ROUND_UP(len);
+ if (!pages) return _EINVAL;
page_t page;
if (addr != 0) {
if (PGOFFSET(addr) != 0)