특정 PTE에 대한 NX 비트를 수동으로 설정

특정 PTE에 대한 NX 비트를 수동으로 설정

커널 4.16.7이 설치된 Ubuntu에서 사용자 정의 시스템 호출을 작성 중이며 특정 페이지 테이블 항목의 NX 비트를 설정하고 싶습니다. 지금까지 나는 이 코드를 가지고 있으며, 원하는 PTE를 얻기 위해 페이지 테이블 탐색을 수행한 다음 NX 비트를 설정하려고 합니다.

pgd = pgd_offset(mm, addr);
if (pgd_none(*pgd) || pgd_bad(*pgd)){
    printk("Invalid pgd");
    return -1;
}

p4d = p4d_offset(pgd, addr);
if (p4d_none(*p4d) || p4d_bad(*p4d)){
    printk("Invalid p4d");
    return -1;
}

pud = pud_offset(p4d, addr);
if (pud_none(*pud) || pud_bad(*pud)){
    printk("Invalid pud");
    return -1;
}

pmd = pmd_offset(pud, addr);
if (pmd_none(*pmd) || pmd_bad(*pmd)){
    printk("Invalid pmd");
    return -1;
}

ptep = pte_offset_map(pmd, addr);
if (!ptep){
    printk("Invalid ptep");
    return -1;
}
pte = *ptep;

if (pte_present(pte)){
    printk("pte_set_flags");
    printk("NX bit before:  %d", pte_exec(pte));
    // pte_set_flags(pte, _PAGE_NX);
    // printk("NX bit after :  %d", pte_exec(pte));
    printk("pte_clear_flags");
    // pte_clear_flags(pte, _PAGE_NX); // Same as pte_mkexec()
    pte_mkexec(pte);
    printk("NX bit after :  %d", pte_exec(pte));
    page = pte_page(pte);
    if (page){
        printk("Page frame struct is @ %p", page);
    }

    pte_unmap(ptep);
}

하지만 작동하지 않습니다. 모든 printk명령은 동일한 결과를 보여줍니다. 어떤 통찰력이 있습니까?

답변1

그래서 제가 직접 찾았습니다. 코드는 아래와 같이 표시됩니다.

struct vm_area_struct *vma;
unsigned long oldflags, newflags, pfn;

vma = find_extend_vma(mm, addr);
oldflags = vma->vm_flags;
newflags = oldflags &= ~VM_EXEC;

//...
//...
//...

if (pte_present(pte)){
    printk("NX bit before: %d", pte_exec(pte));

    pte = pte_modify(pte, vm_get_page_prot(newflags));
    printk("NX bit after:  %d", pte_exec(pte));

    pfn = pte_pfn(pte);

    flush_cache_page(vma, addr, pfn);
    set_pte(ptep, pte);
    flush_tlb_page(vma, addr);
    update_mmu_cache(vma, addr, ptep);

    pte_unmap(ptep);
}

이를 통해 특정 PTE의 NX 비트를 변경합니다.

관련 정보