64-Bit Desktop Kernel Does Not Use NX CPU Flag?

I recently install 64-bit OpenSuse 11.3, the first time I’d used Suse 64-bit - I have to say it has been all good so far, which is great.

However, today I was experimenting with a tool that tests vulnerabilities which should be remedied if using an NX capable processor. I am running 2.6.34.7-0.5-desktop on an Intel Core i7. I downloaded a 64-bit compatible version of paxtest from :

wget http://grsecurity.net/~spender/paxtest-0.9.9.tgz

(If you get this make sure to use the above if compiling in a 64-bit environment, earlier versions will not build nicely.)

Running it I was surprised to see that the NX capabilities of the CPU do not appear to be honored.

Here are my results:

PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter@adamantix.org>
Released under the GNU Public Licence version 2 or later

Mode: blackhat
Linux callandor 2.6.34.7-0.5-desktop #1 SMP PREEMPT 2010-10-25 08:40:12 +0200 x86_64 x86_64 x86_64 GNU/Linux

Executable anonymous mapping : Killed
Executable bss : Killed
Executable data : Killed
Executable heap : Killed
Executable stack : Killed
Executable shared library bss : Killed
Executable shared library data : Killed
Executable anonymous mapping (mprotect) : Vulnerable
==>Executable bss (mprotect) : Vulnerable
==>Executable data (mprotect) : Vulnerable
==>Executable heap (mprotect) : Vulnerable
==>Executable stack (mprotect) : Vulnerable
==>Executable shared library bss (mprotect) : Vulnerable
==>Executable shared library data (mprotect): Vulnerable
==>Writable text segments : Vulnerable
Anonymous mapping randomisation test : 28 bits (guessed)
Heap randomisation test (ET_EXEC) : No randomisation
Heap randomisation test (PIE) : 28 bits (guessed)
Main executable randomisation (ET_EXEC) : No randomisation
Main executable randomisation (PIE) : 28 bits (guessed)
Shared library randomisation test : 28 bits (guessed)
Stack randomisation test (SEGMEXEC) : 28 bits (guessed)
Stack randomisation test (PAGEEXEC) : 28 bits (guessed)
Return to function (strcpy) : paxtest: return address contains a NULL byte.
Return to function (memcpy) : Vulnerable
Return to function (strcpy, PIE) : paxtest: return address contains a NULL byte.
Return to function (memcpy, PIE) : Vulnerable

From my understanding, NX was one of the big deals a few years back and was a main feature provided by the PAE kernel. I would have thought the default 64-bit kernel would have included NX support. I also thought per NX bit - Wikipedia, the free encyclopedia that NX support has been in the kernel since 2.6.8

I looked in config-2.6.34.7-0.5-desktop but did not see anything related to NX/XD config wise, other than DEBUG_NX_TEST

What am I missing here? Shouln’t this test fail in the Executable [bss, stack, etc.] tests on 64-bit with a NX capable processor?

Cheers,
Pete

NX is a hardware feature associated with PAE. However x86_64 processors run in linear mode, and NX has to be reimplemented for this, without the PAE, which isn’t needed anymore. It seems AMD did implement it, but Intel didn’t implement NX (they called XD, Execute Disable) for some early processors. How recent is your processor?

x86-64 - Wikipedia, the free encyclopedia

Scroll down to Older Implementations

What does this return:

grep -w nx /proc/cpuinfo

Hi Ken,

Thanks for the info. I’m still a bit confused though - I do understand NX is a CPU feature, but is it not actually used then if present with a 64bit kernel ? For example, I have a new Intel i7 CPU - here all the cpu flags from /proc/cpuinfo:

flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology nonstop_tsc aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 popcnt lahf_lm tpr_shadow vnmi flexpriority ept vpid

It shows NX is supported (and lm of course). Previously I understood that nx was used with PAE kernels, whether 32 or 64 bit, together with bit 63 in the page table entry - in other words NX worked with PAE to prevent executing code in pages marked as no execute. All good.

However, does this then mean that in today’s 64-bit kernels (which don’t need PAE of course) that memory pages and the page table do not use the nx bit? If so, why is nx still around? So, I figure it must be implemented somehow, but I don’t quite get it.

Thanks for helping to clarify - I appreciate it.

Cheers,
Pete

What I meant is that on 64-bit CPUs NX has to be implemented a different way from 32-bit CPUs, but the functionality is the same. It is still useful for preventing execution of non-executable pages. It is a feature that is not tied to PAE; it just happened to be rolled out with PAE in the same models of 32-bit CPUs (again with few exceptions). However the kernel has to take advantage of it. Maybe you’ll to do a bit more searching to find out how to check if NX is enabled in a given kernel.

Hi Ken,

Searching is where I started of course, which lead to using paxtest to determine if NX was functioning. After finding and compiling paxtest, running it, seeing that it appears to not prevent code execution as I would expect I then checked in the kernel config file for any reference to NX - there is only one, and it is for a test case.

I understand that NX is implemented differently in 64-bit kernels vs PAE, I just don’t get why the paxtest results I originally posted show that it appears not to function quite as I would have expected it to. (See results posted.)

I’ll figure it out, but I just thought that since Google is not being particularly helpful, that the forum might be a place to get input.