no-execute in 32bits protected mode without PAE

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
brunexgeek
Member
Member
Posts: 45
Joined: Wed Dec 25, 2013 11:51 am

no-execute in 32bits protected mode without PAE

Post by brunexgeek »

Hey guys!

I was thinking about how to avoid some malicious or buggy software to execute code in data memory. With PAE, we have the NX bit to protected pages against execution, but without it we have no hardware support.

I did some search and found little information. I read about a technique used by PaX (from Wikipedia):
On IA-32 architectures, NX bit emulation is done by changing the permission level of non-executable pages. The Supervisor bit is overloaded to represent NX. This causes a protection fault when access occurs to the page and it is not yet cached in the translation lookaside buffer. In this case, the memory management unit alerts the operating system; on IA-32, the MMU typically has separate TLB caches for execution (ITLB) and read/write (DTLB), so this fault also allows Linux and PaX to determine whether the program was trying to execute the page as code. If an ITLB fault is caught, the process is terminated; otherwise Linux forces a DTLB load to be allowed, and execution continues as normal.
I think that a simple (and poor :| ) implementation could be to check at context switching if the EIP of the thread (next and/or previous thread) it's within a page marked as data (e.i. if the read/write bit of the page is 'write' I assume no-execute).

Has anyone implemented something like this?

PS: sorry if the english is bad! [-o<
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: no-execute in 32bits protected mode without PAE

Post by Owen »

OpenBSD has a much better solution, implemented by "bifucrating" application binaries into two halves with a 1GB virtual address gap between them.

The user code segment stretches from 0GB to 1GB; the user data segment stretches from 0Gb to 2GB (as necessary).
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: no-execute in 32bits protected mode without PAE

Post by sortie »

The easiest solution is to realize that some processors are bad and portably is bad. Don't support stupid CPUs. All x86_64 systems have NX (Right? I quite hope so). You could gain simplicity, security, and elegance if you limit yourself to processors with NX.
Nable
Member
Member
Posts: 453
Joined: Tue Nov 08, 2011 11:35 am

Re: no-execute in 32bits protected mode without PAE

Post by Nable »

brunexgeek wrote: Has anyone implemented something like this?
Software DEP in Win32 and NX-approximation in old Linux kernels are examples of this.
AFAIK, they're using segment limit for CS (code segment) to achieve this approximation. But segmentation is strongly discouraged nowadays, so you probably shouldn't waste your time to implement such support.
brunexgeek
Member
Member
Posts: 45
Joined: Wed Dec 25, 2013 11:51 am

Re: no-execute in 32bits protected mode without PAE

Post by brunexgeek »

Owen wrote:OpenBSD has a much better solution, implemented by "bifucrating" application binaries into two halves with a 1GB virtual address gap between them.
The user code segment stretches from 0GB to 1GB; the user data segment stretches from 0Gb to 2GB (as necessary).
I read something about this method, but I was looking for another method instead separate my code and data segments. BTW this seems work well.
Nable wrote:Software DEP in Win32 and NX-approximation in old Linux kernels are examples of this.
AFAIK, they're using segment limit for CS (code segment) to achieve this approximation. But segmentation is strongly discouraged nowadays, so you probably shouldn't waste your time to implement such support.
Personally I really prefer don't use segmentation because this way I would have to implement the segmentation (for old machines) and after the support for NX (for newer machines). And even assuming that the choice would be taken in the compilation time, my code can became hard to maintain (I'm wrong?).
sortie wrote:The easiest solution is to realize that some processors are bad and portably is bad. Don't support stupid CPUs. All x86_64 systems have NX (Right? I quite hope so). You could gain simplicity, security, and elegance if you limit yourself to processors with NX.
Maybe you are right. My OS can follow the Windows 8 steps: don't run if the machine don't support NX 8)
BTW you know what the recent Linux kernels do to address this problem?
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Re: no-execute in 32bits protected mode without PAE

Post by Brynet-Inc »

Nable wrote:AFAIK, they're using segment limit for CS (code segment) to achieve this approximation. But segmentation is strongly discouraged nowadays, so you probably shouldn't waste your time to implement such support.
This is actually one of the few remaining legitimate uses for x86 segmentation.
sortie wrote:Don't support stupid CPUs. All x86_64 systems have NX (Right? I quite hope so)
Some early Intel clones didn't implement the NX bit. I believe the segmentation trick is still used on them.
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
Post Reply