--- zzzz-none-000/linux-2.6.19.2/mm/mremap.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/mm/mremap.c 2007-01-19 14:42:56.000000000 +0000 @@ -107,6 +107,12 @@ pte = ptep_clear_flush(vma, old_addr, old_pte); /* ZERO_PAGE can be dependant on virtual addr */ pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr); + +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC)) + pte_exprotect(pte); +#endif + set_pte_at(mm, new_addr, new_pte, pte); } @@ -255,6 +261,7 @@ struct vm_area_struct *vma; unsigned long ret = -EINVAL; unsigned long charged = 0; + unsigned long task_size = TASK_SIZE; if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) goto out; @@ -273,6 +280,15 @@ if (!new_len) goto out; +#ifdef CONFIG_PAX_SEGMEXEC + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) + task_size = SEGMEXEC_TASK_SIZE; +#endif + + if (new_len > task_size || addr > task_size-new_len || + old_len > task_size || addr > task_size-old_len) + goto out; + /* new_addr is only valid if MREMAP_FIXED is specified */ if (flags & MREMAP_FIXED) { if (new_addr & ~PAGE_MASK) @@ -280,16 +296,13 @@ if (!(flags & MREMAP_MAYMOVE)) goto out; - if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len) + if (new_addr > task_size - new_len) goto out; /* Check if the location we're moving into overlaps the * old location at all, and fail if it does. */ - if ((new_addr <= addr) && (new_addr+new_len) > addr) - goto out; - - if ((addr <= new_addr) && (addr+old_len) > new_addr) + if (addr + old_len > new_addr && new_addr + new_len > addr) goto out; ret = do_munmap(mm, new_addr, new_len); @@ -323,6 +336,14 @@ ret = -EINVAL; goto out; } + +#ifdef CONFIG_PAX_SEGMEXEC + if (vma->vm_flags & VM_MIRROR) { + ret = -EINVAL; + goto out; + } +#endif + /* We can't remap across vm area boundaries */ if (old_len > vma->vm_end - addr) goto out; @@ -356,7 +377,7 @@ if (old_len == vma->vm_end - addr && !((flags & MREMAP_FIXED) && (addr != new_addr)) && (old_len != new_len || !(flags & MREMAP_MAYMOVE))) { - unsigned long max_addr = TASK_SIZE; + unsigned long max_addr = task_size; if (vma->vm_next) max_addr = vma->vm_next->vm_start; /* can we just expand the current mapping? */ @@ -374,6 +395,7 @@ addr + new_len); } ret = addr; + track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags); goto out; } } @@ -384,8 +406,8 @@ */ ret = -ENOMEM; if (flags & MREMAP_MAYMOVE) { + unsigned long map_flags = 0; if (!(flags & MREMAP_FIXED)) { - unsigned long map_flags = 0; if (vma->vm_flags & VM_MAYSHARE) map_flags |= MAP_SHARED; @@ -395,7 +417,12 @@ if (new_addr & ~PAGE_MASK) goto out; } + map_flags = vma->vm_flags; ret = move_vma(vma, addr, old_len, new_len, new_addr); + if (!(ret & ~PAGE_MASK)) { + track_exec_limit(current->mm, addr, addr + old_len, 0UL); + track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags); + } } out: if (ret & ~PAGE_MASK)