Manually set NX bit of specific PTE
Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
On Ubuntu with kernel 4.16.7 I am writing a custom system call and, as the title states, I want to set the NX bit of a specific Page Table Entry. So far I have this piece of code, where I am doing a page table walk to get the PTE I want and then try to set its NX bit:
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);
but it doesn't work. All the printk
commands show the same result. Any insight?
Thanks in advance!
64bit table nx
add a comment |Â
up vote
2
down vote
favorite
On Ubuntu with kernel 4.16.7 I am writing a custom system call and, as the title states, I want to set the NX bit of a specific Page Table Entry. So far I have this piece of code, where I am doing a page table walk to get the PTE I want and then try to set its NX bit:
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);
but it doesn't work. All the printk
commands show the same result. Any insight?
Thanks in advance!
64bit table nx
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
On Ubuntu with kernel 4.16.7 I am writing a custom system call and, as the title states, I want to set the NX bit of a specific Page Table Entry. So far I have this piece of code, where I am doing a page table walk to get the PTE I want and then try to set its NX bit:
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);
but it doesn't work. All the printk
commands show the same result. Any insight?
Thanks in advance!
64bit table nx
On Ubuntu with kernel 4.16.7 I am writing a custom system call and, as the title states, I want to set the NX bit of a specific Page Table Entry. So far I have this piece of code, where I am doing a page table walk to get the PTE I want and then try to set its NX bit:
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);
but it doesn't work. All the printk
commands show the same result. Any insight?
Thanks in advance!
64bit table nx
64bit table nx
edited Aug 10 at 8:47
asked Aug 8 at 9:05
Mar Tsan
114
114
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
0
down vote
accepted
So I found it by myself. The code is as follows:
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);
and thus the NX bit of a specific PTE is changed.
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
So I found it by myself. The code is as follows:
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);
and thus the NX bit of a specific PTE is changed.
add a comment |Â
up vote
0
down vote
accepted
So I found it by myself. The code is as follows:
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);
and thus the NX bit of a specific PTE is changed.
add a comment |Â
up vote
0
down vote
accepted
up vote
0
down vote
accepted
So I found it by myself. The code is as follows:
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);
and thus the NX bit of a specific PTE is changed.
So I found it by myself. The code is as follows:
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);
and thus the NX bit of a specific PTE is changed.
edited Aug 17 at 9:21
answered Aug 17 at 9:14
Mar Tsan
114
114
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f461234%2fmanually-set-nx-bit-of-specific-pte%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password