Manually set NX bit of specific PTE

The name of the pictureThe name of the pictureThe name of the pictureClash 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!










share|improve this question



























    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!










    share|improve this question

























      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!










      share|improve this question















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Aug 10 at 8:47

























      asked Aug 8 at 9:05









      Mar Tsan

      114




      114




















          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.






          share|improve this answer






















            Your Answer







            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "106"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            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






























            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.






            share|improve this answer


























              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.






              share|improve this answer
























                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.






                share|improve this answer














                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.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Aug 17 at 9:21

























                answered Aug 17 at 9:14









                Mar Tsan

                114




                114



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    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













































































                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Bahrain

                    Postfix configuration issue with fips on centos 7; mailgun relay