mirror of
https://github.com/drasko/codezero.git
synced 2026-09-19 11:50:21 +02:00
Fixed various bugs in user buffer validation/mapping and mmap() syscall path.
This commit is contained in:
@@ -61,7 +61,7 @@ void *mmap2(void *start, size_t length, int prot, int flags, int fd, off_t pgoff
|
|||||||
errno = -(int)ret;
|
errno = -(int)ret;
|
||||||
return MAP_FAILED;
|
return MAP_FAILED;
|
||||||
}
|
}
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ void handle_requests(void)
|
|||||||
case L4_IPC_TAG_MMAP: {
|
case L4_IPC_TAG_MMAP: {
|
||||||
struct sys_mmap_args *args = (struct sys_mmap_args *)mr[0];
|
struct sys_mmap_args *args = (struct sys_mmap_args *)mr[0];
|
||||||
ret = (int)sys_mmap(sender, args);
|
ret = (int)sys_mmap(sender, args);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case L4_IPC_TAG_MUNMAP: {
|
case L4_IPC_TAG_MUNMAP: {
|
||||||
ret = sys_munmap(sender, (void *)mr[0], (unsigned long)mr[1]);
|
ret = sys_munmap(sender, (void *)mr[0], (unsigned long)mr[1]);
|
||||||
|
|||||||
@@ -615,7 +615,7 @@ int sys_read(struct tcb *task, int fd, void *buf, int count)
|
|||||||
|
|
||||||
/* Check user buffer validity. */
|
/* Check user buffer validity. */
|
||||||
if ((ret = pager_validate_user_range(task, buf,
|
if ((ret = pager_validate_user_range(task, buf,
|
||||||
(unsigned long)(buf + count),
|
(unsigned long)count,
|
||||||
VM_READ)) < 0)
|
VM_READ)) < 0)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
@@ -685,7 +685,7 @@ int sys_write(struct tcb *task, int fd, void *buf, int count)
|
|||||||
|
|
||||||
/* Check user buffer validity. */
|
/* Check user buffer validity. */
|
||||||
if ((ret = pager_validate_user_range(task, buf,
|
if ((ret = pager_validate_user_range(task, buf,
|
||||||
(unsigned long)(buf + count),
|
(unsigned long)count,
|
||||||
VM_WRITE | VM_READ)) < 0)
|
VM_WRITE | VM_READ)) < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|||||||
+13
-18
@@ -193,7 +193,9 @@ void *do_mmap(struct vm_file *mapfile, unsigned long file_offset,
|
|||||||
|
|
||||||
/* Check invalid map address */
|
/* Check invalid map address */
|
||||||
if (!mmap_address_validate(task, map_address, flags)) {
|
if (!mmap_address_validate(task, map_address, flags)) {
|
||||||
if (!(map_address = mmap_new_address(task, flags, npages)))
|
if (flags & VMA_FIXED)
|
||||||
|
return PTR_ERR(-EINVAL);
|
||||||
|
else if (!(map_address = mmap_new_address(task, flags, npages)))
|
||||||
return PTR_ERR(-ENOMEM);
|
return PTR_ERR(-ENOMEM);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@@ -262,31 +264,22 @@ void *do_mmap(struct vm_file *mapfile, unsigned long file_offset,
|
|||||||
|
|
||||||
/* mmap system call implementation */
|
/* mmap system call implementation */
|
||||||
void *__sys_mmap(struct tcb *task, void *start, size_t length, int prot,
|
void *__sys_mmap(struct tcb *task, void *start, size_t length, int prot,
|
||||||
int flags, int fd, unsigned long pfn)
|
int flags, int fd, unsigned long file_offset)
|
||||||
{
|
{
|
||||||
unsigned long npages = __pfn(page_align_up(length));
|
|
||||||
unsigned long base = (unsigned long)start;
|
|
||||||
struct vm_file *file = 0;
|
|
||||||
unsigned int vmflags = 0;
|
unsigned int vmflags = 0;
|
||||||
|
struct vm_file *file = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Check fd validity */
|
/* Check file validity */
|
||||||
if (!(flags & MAP_ANONYMOUS))
|
if (!(flags & MAP_ANONYMOUS))
|
||||||
if (!task->files->fd[fd].vmfile)
|
if (!task->files->fd[fd].vmfile)
|
||||||
if ((err = file_open(task, fd)) < 0)
|
if ((err = file_open(task, fd)) < 0)
|
||||||
return PTR_ERR(err);
|
return PTR_ERR(err);
|
||||||
|
|
||||||
if (base < task->start || base >= task->end)
|
/* Check file offset is page aligned */
|
||||||
|
if (!is_page_aligned(file_offset))
|
||||||
return PTR_ERR(-EINVAL);
|
return PTR_ERR(-EINVAL);
|
||||||
|
|
||||||
/* Exclude task's stack, text and data from mmappable area in task's space */
|
|
||||||
if (base < task->map_start || base >= task->map_end || !base) {
|
|
||||||
if (flags & MAP_FIXED) /* Its fixed, we cannot satisfy it */
|
|
||||||
return PTR_ERR(-EINVAL);
|
|
||||||
else
|
|
||||||
start = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
* Check that @start does not already have a mapping.
|
* Check that @start does not already have a mapping.
|
||||||
* Check that pfn + npages range is within the file range.
|
* Check that pfn + npages range is within the file range.
|
||||||
@@ -318,7 +311,8 @@ void *__sys_mmap(struct tcb *task, void *start, size_t length, int prot,
|
|||||||
if (prot & PROT_EXEC)
|
if (prot & PROT_EXEC)
|
||||||
vmflags |= VM_EXEC;
|
vmflags |= VM_EXEC;
|
||||||
|
|
||||||
return do_mmap(file, __pfn_to_addr(pfn), task, base, vmflags, npages);
|
return do_mmap(file, file_offset, task, (unsigned long)start,
|
||||||
|
vmflags, __pfn(page_align_up(length)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *sys_mmap(struct tcb *task, struct sys_mmap_args *args)
|
void *sys_mmap(struct tcb *task, struct sys_mmap_args *args)
|
||||||
@@ -332,8 +326,9 @@ void *sys_mmap(struct tcb *task, struct sys_mmap_args *args)
|
|||||||
VM_READ | VM_WRITE)))
|
VM_READ | VM_WRITE)))
|
||||||
return PTR_ERR(-EINVAL);
|
return PTR_ERR(-EINVAL);
|
||||||
|
|
||||||
ret = __sys_mmap(task, args->start, args->length, args->prot,
|
ret = __sys_mmap(task, mapped_args->start, mapped_args->length,
|
||||||
args->flags, args->fd, args->offset);
|
mapped_args->prot, mapped_args->flags, mapped_args->fd,
|
||||||
|
mapped_args->offset);
|
||||||
|
|
||||||
pager_unmap_user_range(mapped_args, sizeof(*args));
|
pager_unmap_user_range(mapped_args, sizeof(*args));
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,6 @@ void *pager_validate_map_user_range(struct tcb *user, void *userptr,
|
|||||||
void pager_unmap_user_range(void *mapped_ptr, unsigned long size)
|
void pager_unmap_user_range(void *mapped_ptr, unsigned long size)
|
||||||
{
|
{
|
||||||
l4_unmap_helper((void *)page_align(mapped_ptr),
|
l4_unmap_helper((void *)page_align(mapped_ptr),
|
||||||
__pfn(page_align(mapped_ptr) + page_align_up(size)));
|
__pfn(page_align_up(size)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user