But if that's the case, then what exactly does the
--no-exec-shield
option to prelink actually *do*? What functionality of ExecShield
(that it doesn't already conflict with) is left for it to disable?
This option affects how prelink chooses the addresses to place libraries
at. The default is --exec-shield when the kernel has exec-shield enabled
at the time prelink is run, and --no-exec-shield if not. Under
--no-exec-shield, it uses the traditional mmap region starting at
0x41000000, which is out of the way of things that want to use fixed
addresses below there. Under --exec-shield, prelink uses addresses
optimized to interact well with addresses that exec-shield randomization
chooses, which may conflict with old assumptions about where "anywhere"
mappings wind up.
The nonselsec.pdf document also states that PIEs are excluded from
prelinking. That makes sense. But if code segments aren't writable
(and I don't believe they are, IIRC), what benefit does PIE actually
bring? Is it trying to make it harder for an attacker to leverage
pre-existing code in the application to launch an exploit?
Yes, that is the point. Many exploits work by jumping to known addresses
in the commonly-found binary of the program being attacked. With PIE,
these addresses are not constant any more. It is the same issue as
exec-shield randomization of mmap locations addresses for dynamically
allocated data (or executable code) pages.