It has been done before - called PaX. Search the Phrack article on PaX. On Wed, Mar 11, 2009 at 10:04 AM, NAHieu <nahieu@xxxxxxxxx> wrote: > > On Wed, Mar 11, 2009 at 10:46 AM, NAHieu <nahieu@xxxxxxxxx> wrote: > > On Tue, Mar 10, 2009 at 4:13 PM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote: > >> Sorry, my mistake, PAE is required yes, and then 32bit Linux Kernel > >> will have NX enabled: > >> > >> PAE can be enabled with CONFIG_X86_PAE (and CONFIG_HIGHMEM64G - > >> possibly needed, which is what the kernel config file for Fedora Core > >> 11 has): > >> > >> In arch/x86/mm/init_32.c: > >> > >> #ifdef CONFIG_X86_PAE > >> set_nx(); > >> if (nx_enabled) > >> printk(KERN_INFO "NX (Execute Disable) protection: active\n"); > >> #endif > > > > That is indeed what happens in the kernel code. However, now I really > > have some doubts now after reading the Intel manual 3A. > > > > According to 3.8.5, PAE mode in x86 reserves all the bits from 36-63 > > to 0. Knowing that bit 63 is for NX, this means NX bit is never on, so > > no page can be set with NX bit. As a result, all the pages in x86 > > cannot prohibit execution. > > > > Meanwhile, 3.10.3 clearly mentions NX bit can be turned on in x86-64 > > (IA32e in Intel term). > > > > So this means NX is really only possible in 64bit OS??? But then why > > Linux 32 turns on NX? > > > > Could anybody confirm this confusion? > > Hmm now I see the reason: 4.13.3 says that the reserved bits are > checked when PAE is on. > > My question still stands: why some (every?) data areas dont prohibit > execution in x86 Linux? > > Thanks, > H > > > > >> On Tue, Mar 10, 2009 at 12:23 PM, NAHieu <nahieu@xxxxxxxxx> wrote: > >>> On Mon, Mar 9, 2009 at 11:50 PM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote: > >>>> as far as I can remember, in x86 architecture, hardware-wise, it is > >>>> NOT possible to enable NX. U may do anything via software, but it > >>>> will not be enabled. NX feature is only for 64bit OS. > >>>> > >>> > >>> No, NX is available for 32bit Linux, as long as PAE is enable. > >>> > >>> I am still stuck here (on 32bit Linux). It seems nobody can shed some > >>> lights in this problem? > >>> > >>> Thanks, > >>> H > >>> > >>> > >>>> On Mon, Mar 9, 2009 at 4:27 AM, NAHieu <nahieu@xxxxxxxxx> wrote: > >>>>> Hi, > >>>>> > >>>>> I inspect my Linux memory, and it seems that there is no area that > >>>>> prohibite execution like I expected (using NX bit in modern CPU). That > >>>>> really surprises me. > >>>>> > >>>>> I looked at some potential data areas exported in System.map file, like: > >>>>> > >>>>> - mark_rodata_ro > >>>>> - sysctl_data > >>>>> - new_cpu_data > >>>>> - boot_cpu_data > >>>>> Looking at the patches supplied by PaX (it is supposed to patch vanilla linux kernel): The following set the section "rodata" as write protected via CR0 register: +.section .rodata,"a",@progbits ENTRY(interrupt) .text @@ -683,12 +742,21 @@ error_code: popl %ecx CFI_ADJUST_CFA_OFFSET -4 /*CFI_REGISTER es, ecx*/ + +#ifdef CONFIG_PAX_KERNEXEC + GET_CR0_INTO_EDX + movl %edx, %esi + orl $X86_CR0_WP, %edx + xorl %edx, %esi + SET_CR0_FROM_EDX +#endif + movl PT_FS(%esp), %edi # get the function address movl PT_ORIG_EAX(%esp), %edx # get the error code movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart mov %ecx, PT_FS(%esp) /*CFI_REL_OFFSET fs, ES*/ - movl $(__USER_DS), %ecx + movl $(__KERNEL_DS), %ecx movl %ecx, %ds And the following is for the ".data" section: -.data +__INITDATA saved_return_addr: .long 0 efi_rt_function_ptr: diff -NurpX linux-2.6.24.4-pax/Documentation/dontdiff linux-2.6.24.4/arch/x86/kernel/entry_32.S linux-2.6.24.4-pax/arch/x86/kernel/entry_32.S --- linux-2.6.24.4/arch/x86/kernel/entry_32.S 2008-01-24 23:58:37.000000000 +0100 +++ linux-2.6.24.4-pax/arch/x86/kernel/entry_32.S 2008-02-29 18:07:50.000000000 +0100 @@ -97,7 +97,7 @@ VM_MASK = 0x00020000 #define resume_userspace_sig resume_userspace #endif -#define SAVE_ALL \ +#define __SAVE_ALL(_DS) \ cld; \ pushl %fs; \ CFI_ADJUST_CFA_OFFSET 4;\ @@ -129,12 +129,26 @@ VM_MASK = 0x00020000 pushl %ebx; \ CFI_ADJUST_CFA_OFFSET 4;\ CFI_REL_OFFSET ebx, 0;\ - movl $(__USER_DS), %edx; \ + movl $(_DS), %edx; \ movl %edx, %ds; \ movl %edx, %es; \ movl $(__KERNEL_PERCPU), %edx; \ movl %edx, %fs +#ifdef CONFIG_PAX_KERNEXEC +#define SAVE_ALL \ + __SAVE_ALL(__KERNEL_DS); \ + GET_CR0_INTO_EDX; \ + movl %edx, %esi; \ + orl $X86_CR0_WP, %edx; \ + xorl %edx, %esi; \ + SET_CR0_FROM_EDX +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS) +#else +#define SAVE_ALL __SAVE_ALL(__USER_DS) +#endif + Thanks. > > >>>>> And all of these areas allow to execute code (because NX=0 there). Is > >>>>> that really desirable? > >>>>> > >>>>> Anybody know for sure which area (easier to check if exported in > >>>>> System.map) doesnt allow execute? > >>>>> > >>>>> I can confirm that NX is active in my machine (reported in dmesg) > >>>>> > >>> > >> > >> > >> > >> -- > >> Regards, > >> Peter Teoh > >> > > -- 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