From 4a7ccc208c95c0d4e4e3712768611939bb39d967 Mon Sep 17 00:00:00 2001 From: Matheus Date: Tue, 30 Jul 2024 20:30:55 -0300 Subject: [PATCH] read/write syscalls: properly handle nbytes = 0 --- kernel-src/sys/syscalls/read.c | 6 ++++-- kernel-src/sys/syscalls/write.c | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/kernel-src/sys/syscalls/read.c b/kernel-src/sys/syscalls/read.c index f49d42b1..9fb1c00b 100644 --- a/kernel-src/sys/syscalls/read.c +++ b/kernel-src/sys/syscalls/read.c @@ -10,8 +10,9 @@ syscallret_t syscall_read(context_t *context, int fd, void *buffer, size_t size) .ret = -1 }; - void *kernelbuff = vmm_map(NULL, size, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL); + void *kernelbuff = vmm_map(NULL, size == 0 ? 1 : size, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL); if (kernelbuff == NULL) { + printf("read enomem: %d %p %lu\n", fd, buffer, size); ret.errno = ENOMEM; return ret; } @@ -28,6 +29,7 @@ syscallret_t syscall_read(context_t *context, int fd, void *buffer, size_t size) ret.errno = 0; goto cleanup; } + size_t bytesread; uintmax_t offset = file->offset; ret.errno = vfs_read(file->vnode, kernelbuff, size, file->offset, &bytesread, fileflagstovnodeflags(file->flags)); @@ -42,6 +44,6 @@ cleanup: if (file) fd_release(file); - vmm_unmap(kernelbuff, size, 0); + vmm_unmap(kernelbuff, size == 0 ? 1 : size, 0); return ret; } diff --git a/kernel-src/sys/syscalls/write.c b/kernel-src/sys/syscalls/write.c index 046c5731..eede6ae0 100644 --- a/kernel-src/sys/syscalls/write.c +++ b/kernel-src/sys/syscalls/write.c @@ -8,7 +8,7 @@ syscallret_t syscall_write(context_t *context, int fd, void *buffer, size_t size .ret = -1 }; - void *kernelbuff = vmm_map(NULL, size, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL); + void *kernelbuff = vmm_map(NULL, size == 0 ? 1 : size, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL); if (kernelbuff == NULL) { ret.errno = ENOMEM; return ret; @@ -21,16 +21,16 @@ syscallret_t syscall_write(context_t *context, int fd, void *buffer, size_t size goto cleanup; } + ret.errno = usercopy_fromuser(kernelbuff, buffer, size); + if (ret.errno) + goto cleanup; + if (size == 0) { ret.ret = 0; ret.errno = 0; goto cleanup; } - ret.errno = usercopy_fromuser(kernelbuff, buffer, size); - if (ret.errno) - goto cleanup; - size_t byteswritten; uintmax_t offset = file->offset; @@ -55,6 +55,6 @@ cleanup: if (file) fd_release(file); - vmm_unmap(kernelbuff, size, 0); + vmm_unmap(kernelbuff, size == 0 ? 1 : size, 0); return ret; }