Few map_address fixes to mmap()

This commit is contained in:
Bahadir Balban
2008-03-13 00:56:21 +00:00
parent d27f942702
commit 4f87b6672e

View File

@@ -407,13 +407,13 @@ unsigned long find_unmapped_area(unsigned long npages, struct tcb *task)
/* If no vmas, first map slot is available. */ /* If no vmas, first map slot is available. */
if (list_empty(&task->vm_area_list)) if (list_empty(&task->vm_area_list))
return __pfn(task->map_start); return USER_AREA_START;
/* First vma to check our range against */ /* First vma to check our range against */
vma = list_entry(task->vm_area_list.next, struct vm_area, list); vma = list_entry(task->vm_area_list.next, struct vm_area, list);
/* Start searching from task's end of data to start of stack */ /* Start searching from task's end of data to start of stack */
while (pfn_end <= __pfn(task->map_end)) { while (pfn_end <= __pfn(USER_AREA_END)) {
/* If intersection, skip the vma and fast-forward to next */ /* If intersection, skip the vma and fast-forward to next */
if (vma_intersect(pfn_start, pfn_end, vma)) { if (vma_intersect(pfn_start, pfn_end, vma)) {
@@ -427,10 +427,10 @@ unsigned long find_unmapped_area(unsigned long npages, struct tcb *task)
* Are we out of task map area? * Are we out of task map area?
*/ */
if (vma->list.next == &task->vm_area_list) { if (vma->list.next == &task->vm_area_list) {
if (pfn_end > __pfn(task->map_end)) if (pfn_end > __pfn(USER_AREA_END))
break; /* Yes, fail */ break; /* Yes, fail */
else else /* No, success */
return pfn_start; /* No, success */ return __pfn_to_addr(pfn_start);
} }
/* Otherwise get next vma entry */ /* Otherwise get next vma entry */
@@ -438,8 +438,8 @@ unsigned long find_unmapped_area(unsigned long npages, struct tcb *task)
struct vm_area, list); struct vm_area, list);
continue; continue;
} }
BUG_ON(pfn_start + npages > __pfn(task->map_end)); BUG_ON(pfn_start + npages > __pfn(USER_AREA_END));
return pfn_start; return __pfn_to_addr(pfn_start);
} }
return 0; return 0;
} }
@@ -482,14 +482,11 @@ int do_mmap(struct vm_file *mapfile, unsigned long file_offset, struct tcb *task
} }
/* Check invalid map address */ /* Check invalid map address */
if (map_address == 0 || map_address < task->data_end || if (map_address == 0 || map_address < USER_AREA_START ||
map_address >= task->stack_start) { map_address >= USER_AREA_END) {
/* Address invalid or not specified */
if (flags & VMA_FIXED)
return -EINVAL;
/* Get new map address for region of this size */ /* Get new map address for region of this size */
else if ((int)(map_address = if ((int)(map_address =
find_unmapped_area(npages, task)) < 0) find_unmapped_area(npages, task)) < 0)
return (int)map_address; return (int)map_address;
@@ -526,6 +523,7 @@ int sys_mmap(l4id_t sender, void *start, size_t length, int prot,
int flags, int fd, unsigned long pfn) int flags, int fd, unsigned long pfn)
{ {
unsigned long npages = __pfn(page_align_up(length)); unsigned long npages = __pfn(page_align_up(length));
unsigned long base = (unsigned long)start;
struct vm_file *file = 0; struct vm_file *file = 0;
unsigned int vmflags = 0; unsigned int vmflags = 0;
struct tcb *task; struct tcb *task;
@@ -536,9 +534,17 @@ int sys_mmap(l4id_t sender, void *start, size_t length, int prot,
if ((fd < 0 && !(flags & MAP_ANONYMOUS)) || fd > TASK_FILES_MAX) if ((fd < 0 && !(flags & MAP_ANONYMOUS)) || fd > TASK_FILES_MAX)
return -EINVAL; return -EINVAL;
if ((unsigned long)start < USER_AREA_START || (unsigned long)start >= USER_AREA_END) if (base < USER_AREA_START || base >= USER_AREA_END)
return -EINVAL; return -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 -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.
@@ -568,7 +574,7 @@ int sys_mmap(l4id_t sender, void *start, size_t length, int prot,
vmflags |= VM_EXEC; vmflags |= VM_EXEC;
if ((err = do_mmap(file, __pfn_to_addr(pfn), task, if ((err = do_mmap(file, __pfn_to_addr(pfn), task,
(unsigned long)start, vmflags, npages)) < 0) base, vmflags, npages)) < 0)
return err; return err;
return 0; return 0;