After reading these conversations, per Torvalds and other devs it seems that XPFO's defense on ret2dir is less of a code execution threat, and more a data exposure threat. The term was coined "read2dir" instead.
Thoughts on the map, perhaps move ret2dir under CFI protections, but also split to have read2dir?
On Thu, Apr 18, 2019 at 7:35 AM Khalid Aziz [email protected] wrote:
On 4/17/19 11:41 PM, Kees Cook wrote:
On Wed, Apr 17, 2019 at 11:41 PM Andy Lutomirski [email protected] wrote:
I don't think this type of NX goof was ever the argument for XPFO.
The main argument I've heard is that a malicious user program writes a
ROP payload into user memory (regular anonymous user memory) and then
gets the kernel to erroneously set RSP (not RIP) to point there.
Well, more than just ROP. Any of the various attack primitives. The NX
stuff is about moving RIP: SMEP-bypassing. But there is still basic
SMAP-bypassing for putting a malicious structure in userspace and
having the kernel access it via the linear mapping, etc.
I find this argument fairly weak for a couple reasons. First, if
we're worried about this, let's do in-kernel CFI, not XPFO, to
CFI is getting much closer. Getting the kernel happy under Clang, LTO,
and CFI is under active development. (It's functional for arm64
already, and pieces have been getting upstreamed.)
CFI theoretically offers protection with fairly low overhead. I have not
played much with CFI in clang. I agree with Linus that probability of
bugs in XPFO implementation itself is a cause of concern. If CFI in
Clang can provide us the same level of protection as XPFO does, I
wouldn't want to push for an expensive change like XPFO.
If Clang/CFI can't get us there for extended period of time, does it
make sense to continue to poke at XPFO?
Well, I think CFI will certainly vastly narrow the execution paths
available to an attacker, but what I continue to see XPFO useful for
is stopping attacks that need to locate something in memory. (i.e. not
ret2dir but, like, read2dir.) It's arguable that such attacks would
just use heap, stack, etc to hold such things, but the linear map
remains relatively easy to find/target. But I agree: the protection is
getting more and more narrow (especially with CFI coming down the
pipe), and if it's still a 28% hit, that's not going to be tenable for
anyone but the truly paranoid. :)
All that said, there isn't a very good backward-edge CFI protection
(i.e. ROP defense) on x86 in Clang. The forward-edge looks decent, but
requires LTO, etc. My point is there is still a long path to gaining
CFI in upstream.