カーネル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ビットを変更します。