64bit
手動設置特定 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
命令都顯示相同的結果。有什麼見解嗎?
所以我自己找到了。程式碼如下:
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 位被改變。