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