pmacs3/code_examples/cfi.rst

57 lines
2.2 KiB
ReStructuredText
Raw Normal View History

Control Flow Integrity
======================
Control-Flow Integrity is a technique used to insure a security
property, namely the targets of all instructions that alter control
flow (ie, branch instructions). To do this they use a combination of
static analysis and dynamic checks.
They then give a number of examples of how to one could use CFI to
improve other existing control flow based tools, including SFI and
shadow stacks. Finally, they give a brief look in at the formal theory
behind secure control flow.
Problem to be solved
--------------------
CFI is designed to handle malicious attacks against a
program. Particularly their threat model is that the adversary has
total control over the data memory. This covers a number of practical
attacks, including any that use a "stack smashing" technique to gain
control of the program. This includes many (all?) code injection
attacks, as well as arc-injection attacks.
Contributions
-------------
To enforce the control-flow integrity policy, they first use static
analysis to determine legitimate targets of indirect branches. Second,
they use binary rewriting to insert dynamic checks to insure the
runtime target is one of the acceptable targets. This can be done
because most functions are well behaved, in that the always return to
their callee.
Evaluation
----------
The main strength of this approach is that it offers a practical
defense against arc injection attacks. They used "hand examinations"
of some known windows arc injection attacks, specifically a GDI+ JPEG
flaw.
There are a number of downsides to their CFI prototype. First is the
relatively high overhead, 20% on SPEC without perl. Secondly, it seems
that there are potential problems with programs that use many function
pointers to point to a variety of different functions. Currently CFI
creates equivalence classes of functions (see the lt and gt example).
Next Step
---------
I believe the use of a SDT-based tool instead of the lightweight
binary instrumentation could address a number of the difficulties,
notably performance. I also think a better job could be done grouping
functions with better use of the control flow information to do a
better job partitioning the targets of function pointers.