On 08/15/2017 07:42 AM, Richard Biener wrote:
> 
> Please change the names to omit 'with_', thus just notrack
> and GF_CALL_NOTRACK.
> 
> I think 'notrack' is somewhat unspecific of a name, what prevented
> you to use 'nocet'?
I think we should look for something better than notrack.  I think
"control flow enforcement/CFE" is commonly used for this stuff.  CET is
an Intel marketing name IIRC.

The tracking is for indirect branch/call targets.  So some combination
of cfe, branch/call and track should be sufficient.



> Any idea how to implement a software-based solution efficiently?
> Creating a table of valid destination addresses in a special section
> should be possible without too much work, am I right in that only
> indirect control transfer is checked?  Thus CET assumes the
> code itself cannot be changed (and thus the stack isn't executable)?
Well, there's two broad areas that have to be addressed.

First you need to separate the call stack from the rest of the call
frame, or at least the parts of the call frame that are potentially
vulnerable to overruns.  LLVM has some code to do this.  Essentially any
object in the stack that is not proven to be safely accessed gets put
into a separate stack.  That roughly duplicates the shadow stack
capability.  I think their implementation is just x86 and IIRC doesn't
work in some circumstances -- I'd consider it a proof of concept, not
something ready for production use.


Bernd and I also spec'd a couple more approaches to protect the return
address.  Essentially, the return address turns into a cookie that a
particular caller can use to lookup/map to a real return address.  We
didn't take any of this to completion because it was pretty clear the
ROP mitigation landscape was going to change and make software only
solutions less appealing.

Second you need the indirect branch/call tracking.  I spec'd something
out in this space with Intel's engineers years ago.  Essentially
building tables of valid targets for indirect branches and checking
instrumentation.   You can have a global table, per-DSO tables or you
can have a per-branch table.  It gets a little hairy in mixed mode
environments.  But it basically works how you'd expect.  Indirect
branches/calls turn into something considerably more complex as do the
branch/call targets if you have access to something like a
last-taken-branch.

Jeff

Reply via email to