Re: Kernel Executable Pages

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thanks Peter for the great explanation!

I'm working towards modifiying the kernel by adding a new layer so
luckily I have the change_page_attr_set available to me.

Thanks,
Asim

On 7/15/08, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote:
> This is a feature of the Intel CPU - called the NX bit.   Once turned
> on, it is a hardware feature whereby u can specify whether the code is
> made executeable or not.   As of 2nd edition of Understanding Linux
> Kernel, it is still mentioned that x86 cannot distinguished between
> executeable and non-executable memory.   But later Intel introduced
> this bit.
>
> Lookup all the codes for implementing this in arch/x86/mm.
>
> For eg, init_32.c - u can specify to disable this feature via
> "noexec=off" at the kernel bootup prompt.
>
>  * Control non executable mappings.
>  *
>  * on      Enable
>  * off     Disable
>  */
> static int __init noexec_setup(char *str)
> {
>         if (!str || !strcmp(str, "on")) {
>                 if (cpu_has_nx) {
>                         __supported_pte_mask |= _PAGE_NX;
>                         disable_nx = 0;
>                 }
>         } else {
>                 if (!strcmp(str, "off")) {
>                         disable_nx = 1;
>                         __supported_pte_mask &= ~_PAGE_NX;
>                 } else {
>                         return -EINVAL;
>
>
> Or in pageattr.c:
>
> /*
>  * Certain areas of memory on x86 require very specific protection flags,
>  * for example the BIOS area or kernel text. Callers don't always get this
>  * right (again, ioremap() on BIOS memory is not uncommon) so this function
>  * checks and fixes these known static required protection bits.
>  */
> static inline pgprot_t static_protections(pgprot_t prot, unsigned long
> address,
>                                    unsigned long pfn)
> {
>         pgprot_t forbidden = __pgprot(0);
>
>         /*
>          * The BIOS area between 640k and 1Mb needs to be executable for
>          * PCI BIOS based config access (CONFIG_PCI_GOBIOS) support.
>          */
>         if (within(pfn, BIOS_BEGIN >> PAGE_SHIFT, BIOS_END >> PAGE_SHIFT))
>                 pgprot_val(forbidden) |= _PAGE_NX;
>
>         /*
>          * The kernel text needs to be executable for obvious reasons
>          * Does not cover __inittext since that is gone later on. On
>          * 64bit we do not enforce !NX on the low mapping
>          */
>         if (within(address, (unsigned long)_text, (unsigned long)_etext))
>                 pgprot_val(forbidden) |= _PAGE_NX;
>
>         /*
>          * The .rodata section needs to be read-only. Using the pfn
>          * catches all aliases.
>          */
>         if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT,
>                    __pa((unsigned long)__end_rodata) >> PAGE_SHIFT))
>                 pgprot_val(forbidden) |= _PAGE_RW;
>
>         prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
>
>         return prot;
> }
>
> Read the comment of this function - basically, it is saying that
> certain ranges of the page frame, if it fall within a certain range of
> the physical address, will have certain page protection properties
> (set into the memory descriptor) - like read/write/executeable.
>
> And according to its definition in pgtable.h:
>
> #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
> #define _PAGE_NX        (_AT(pteval_t, 1) << _PAGE_BIT_NX)
> #else
> #define _PAGE_NX        (_AT(pteval_t, 0))
> #endif
>
> Only 64-bit x86 have this feature enabled.
>
> What can u do about it?
>
> One way is to disable it via command line as mentioned above, another
> way is understand enough of change_page_attr_set() (in
> pageattr.c) to do what u want to do - but it is also a static
> function, so inside your module this function is not visible to you.
>
> It is just a memory descriptor thing, so u can manipulate it any other
> way u want to as well, but the TLB have to be flush, per-cpu.
>
> CMIW.
>
> Thanks.
>
>
> On Wed, Jul 16, 2008 at 1:51 AM, Asim <linkasim@xxxxxxxxx> wrote:
>> The itf is actually addr variable . That was a typo while formatting
>> code in the mail.
>>
>> Regards,
>> Asim
>>
>> On 7/15/08, Asim <linkasim@xxxxxxxxx> wrote:
>>> I'm allocation some function pointers and they were not executable. I
>>> wanted to make them executable. I was able to fix my problem. Let me
>>> know if there is any bug in what I did.
>>>
>>> my_array_of _fn_pointers = kmalloc(sizeof
>>> your_favourite_fn_ptr_struct_here, GFP_KERNEL);
>>>
>>>  addr = my_array_of _fn_pointers ;
>>>  addr_end = (unsigned long) my_array_of _fn_pointers + (unsigned long)
>>> sizeof(your_favourite_fn_ptr_struct_here);
>>>
>>>   /* Make the memory allocated executable. */
>>>   for (; addr < addr_end; addr += PAGE_SIZE)
>>>     change_page_attr(virt_to_page(itf), 1, PAGE_KERNEL_EXEC);
>>>
>>>   printk ("Making the pages executable.\n");
>>>   global_flush_tlb();
>>>
>>> It seems to work fine so far.
>>>
>>> Regards,
>>> Asim Kadav
>>>
>>> On 7/15/08, Sandeep K Sinha <sandeepksinha@xxxxxxxxx> wrote:
>>>> Can you be a bit more specific ?
>>>>
>>>> On Tue, Jul 15, 2008 at 9:55 PM, Asim <linkasim@xxxxxxxxx> wrote:
>>>>> Hi,
>>>>>
>>>>> I try to allocate memory to generate some executable code in memory.
>>>>> But when i try to execute - I get the following error "kernel tried to
>>>>> execute NX-protected page - exploit attempt? (uid: 0)". Is there some
>>>>> different way to allocate executable memory (and not data). Kindly
>>>>> help.
>>>>>
>>>>> Regards,
>>>>> Asim
>>>>>
>>>>> --
>>>>> To unsubscribe from this list: send an email with
>>>>> "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
>>>>> Please read the FAQ at http://kernelnewbies.org/FAQ
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Regards,
>>>> Sandeep.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> "To learn is to change. Education is a process that changes the
>>>> learner."
>>>>
>>>
>>
>> --
>> To unsubscribe from this list: send an email with
>> "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
>> Please read the FAQ at http://kernelnewbies.org/FAQ
>>
>>
>
>
>
> --
> Regards,
> Peter Teoh
>

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux