diff options
Diffstat (limited to 'kernel/vm/mmap.c')
-rw-r--r-- | kernel/vm/mmap.c | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/kernel/vm/mmap.c b/kernel/vm/mmap.c index ce932de..a298df4 100644 --- a/kernel/vm/mmap.c +++ b/kernel/vm/mmap.c @@ -70,7 +70,7 @@ long do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off, } // check if len is not zero (len is an unsigned value, so it is always positive) - if (len == 0) + if ((ssize_t) len <= 0) { return -EINVAL; } @@ -87,8 +87,8 @@ long do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off, return -EINVAL; } - // check if fd is not a valid file descriptor and MAP_ANON was not set - if (fd < 0 && (flags & MAP_ANON) == 0) + // check if the fd is valid and MAP_ANON was not set + if (((fd < 0 || fd >= NFILES) || curproc->p_files[fd] == NULL) && !(flags & MAP_ANON)) { return -EBADF; } @@ -96,10 +96,10 @@ long do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off, // check if a file mapping was requested, but fd is not open for reading // file error checking is done in if statement below file_t *file = NULL; - if (fd >= 0 && (flags & MAP_ANON) == 0) + if (fd >= 0 && fd < NFILES) { // get the file and check if it is valid - file = fget(fd); + file = curproc->p_files[fd]; if (file == NULL) { return -EBADF; @@ -110,7 +110,6 @@ long do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off, // check if the file's vnode's mmap operation doesn't exist if (file->f_vnode->vn_ops == NULL || file->f_vnode->vn_ops->mmap == NULL) { - fput(&file); return -ENODEV; } @@ -119,32 +118,26 @@ long do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off, // check if thef FMODE_READ flag is not set if ((file->f_mode & FMODE_READ) == 0) { - fput(&file); return -EACCES; } // check if append mode is set and PROT_WRITE is set if ((prot & PROT_WRITE) && (file->f_mode & FMODE_APPEND)) { - fput(&file); return -EACCES; } - // check if MAP_SHARED was requested and PROT_WRITE is set, but fd is not open in read/write (O_RDWR) mode - if ((flags & MAP_SHARED) && (prot & PROT_WRITE) && (file->f_mode & FMODE_READ) == 0) + // if MAP_SHARED was requested and PROT_WRITE is set, but fd is not open in read/write (O_RDWR) mode. + if ((flags & MAP_SHARED) && (prot & PROT_WRITE) && (file->f_mode & FMODE_WRITE) == 0) { - fput(&file); return -EACCES; } // check if PROT_WRITE is set, but the file has FMODE_APPEND specified if ((prot & PROT_WRITE) && (file->f_mode & FMODE_APPEND)) { - fput(&file); return -EACCES; } - - fput(&file); } @@ -167,20 +160,18 @@ long do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off, return err; } - // set ret if it was provided void *start = PN_TO_ADDR(vma->vma_start); - if (ret) - { - *ret = start; - } - // flush the TLB tlb_flush_range( (uintptr_t) start, PAGE_SIZE * (vma->vma_end - vma->vma_start) ); - // return 0 on success + // set ret if it was provided and return 0 on success + if (ret) + { + *ret = start; + } return 0; } @@ -212,13 +203,17 @@ long do_munmap(void *addr, size_t len) } // Check if len is in bounds - if (len > USER_MEM_HIGH || len == 0) + if (len > USER_MEM_HIGH || len <= 0) { return -EINVAL; } // Check if the addr is out of range of the user address space - if ((uintptr_t)addr < USER_MEM_LOW || (uintptr_t)addr + len > USER_MEM_HIGH) + if ( + (uintptr_t)addr < USER_MEM_LOW + || (uintptr_t)addr > USER_MEM_HIGH + || (uintptr_t)addr + len > USER_MEM_HIGH + ) { return -EINVAL; } @@ -227,9 +222,8 @@ long do_munmap(void *addr, size_t len) size_t start = ADDR_TO_PN(addr); size_t end = ADDR_TO_PN(PAGE_ALIGN_UP((uintptr_t)addr + len)); long ret = vmmap_remove( - curproc->p_vmmap, - start, - end - start - ); + curproc->p_vmmap, + start, + end - start); return ret; }
\ No newline at end of file |