Subject: non-executable mappings
To: None <tech-kern@netbsd.org>
From: Chuck Silvers <chuq@chuq.com>
List: tech-kern
Date: 07/20/2003 15:03:14
hi folks,

I've started having a bit of time for netbsd again lately,
so I'm trying to finish incorporating the non-executable-mapping
work from openbsd.  the current diff is at:

	ftp://ftp.netbsd.org/pub/NetBSD/misc/chs/noexec/diff.20030720

here's the status of the various pmaps:

working
	alpha
	i386
	powerpc/oea
	sparc
	sparc64

not implemented
	amd64			(I don't have hardware)
	hppa			(port isn't LWP'd)
	powerpc/ibm4xx		(-current didn't work on my explora)
	sh5			(I don't have hardware)

not possible due to hardware constraints
	acorn26 ?
	arm32
	m68k
	mips
	ns32k ?
	sh3
	sun2
	sun3
	vax


please correct me if I'm wrong about any of the not-possibles.


stuff left to do:

 - there's a hack in the sparc pmap that turns pmap_protect() into
   pmap_remove() for hypersparcs.  if I remove that, I get "level 15"
   interrupts while rc is running.

 - on some platforms, the linker creates the ELF header for the data segment
   with permissions of "rwx" instead of "rw".  the ones I wrote down are:

	alpha	data rwx -- static + dynamic
	sparc	data rwx -- dynamic

   maybe this will magically be fixed with the newer toolchain, let's hope.

 - on powerpc/oea, the hardware only does execute permission on a "segment"
   granularity, where a segment is 256MB.  ideally the linker would arrange
   to start the data section at 0x10000000 so that it's in a different
   ppc segment than the text.  then we can stuff shlib code in segment 0
   after the program text and all will be happy.

 - on i386, the hardware-walked page tables don't have an executable bit,
   so the only efficient way to do execute permission is by adjusting the
   segment descriptor used for %cs.  in the current diff, there are two
   code segments, one that covers the whole user address space (like it is
   now), and a new one that doesn't include the stack.  the second descriptor
   is used as long as the user doens't request any executable mappings in
   the stack, but if that happens then the full-address-space segment is used.
   one enhancement to this would be to rearrange the address space so that
   the usual case is for all the executable mappings to be below some boundary,
   then more of the user data, bss and heap could be non-executable.
   the openbsd guys did some more work in this area, but I haven't looked
   into that yet.



in my opinion, none of these issues are serious enough that they need to be
fixed before this change can be committed (but feel free to make an argument
the other way), so I'm looking for people to try out the diff and let me know
if there are any other issues that need to be addressed before this goes in.

there's a test program "noexec.c" in the same directory (also from openbsd).

-Chuck