All pastes #242597 Raw Edit

Stuff

public c v1 · immutable
·published 2006-11-07 13:54 UTC
rendered paste body
static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,    unsigned long start, unsigned long end, unsigned int newflags){    struct mm_struct * mm = vma->vm_mm;    int pages;    int ret;#ifdef CONFIG_PAX_SEGMEXEC    struct vm_area_struct * vma_m = NULL, *prev_m;    unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;    if (vma->vm_flags & VM_MIRROR) {        start_m = vma->vm_start + vma->vm_mirror;        vma_m = find_vma_prev(mm, start_m, &prev_m);        if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {            printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);            return -ENOMEM;        }        start_m = start + vma->vm_mirror;        end_m = end + vma->vm_mirror;        if (newflags & VM_LOCKED)            newflags_m = vma_m->vm_flags | VM_LOCKED;        else            newflags_m = vma_m->vm_flags & ~VM_LOCKED;        ret = __mlock_fixup(vma_m, &prev_m, start_m, end_m, newflags_m);        if (ret)            return ret;    }#endif    ret = __mlock_fixup(vma, prev, start, end, newflags);    if (ret)        return ret;    /*     * vm_flags is protected by the mmap_sem held in write mode.     * It's okay if try_to_unmap_one unmaps a page just after we     * set VM_LOCKED, make_pages_present below will bring it back.     */    vma->vm_flags = newflags;#ifdef CONFIG_PAX_SEGMEXEC    if (vma->vm_flags & VM_MIRROR)        vma_m->vm_flags = newflags_m;#endif    /*     * Keep track of amount of locked VM.     */    pages = (end - start) >> PAGE_SHIFT;    if (newflags & VM_LOCKED) {        pages = -pages;        if (!(newflags & VM_IO))            ret = make_pages_present(start, end);    }    mm->locked_vm -= pages;#ifdef CONFIG_PAX_SEGMEXEC    if (vma->vm_flags & VM_MIRROR)        mm->locked_vm -= pages;#endif    if (ret == -ENOMEM)        ret = -EAGAIN;    return ret;}static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,    unsigned long start, unsigned long end, unsigned int newflags){    struct mm_struct * mm = vma->vm_mm;    pgoff_t pgoff;    int ret = 0;    if (newflags == vma->vm_flags) {        *prev = vma;        goto out;    }    pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);    *prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,              vma->vm_file, pgoff, vma_policy(vma));    if (*prev) {        vma = *prev;        goto out;    }    *prev = vma;    if (start != vma->vm_start) {        ret = split_vma(mm, vma, start, 1);        if (ret)            goto out;    }    if (end != vma->vm_end)        ret = split_vma(mm, vma, end, 0);out:    if (ret == -ENOMEM)        ret = -EAGAIN;    return ret;}