[LLVMdev] [RFC] Simple control-flow integrity

Tom Roeder tmroeder at google.com
Fri Mar 21 11:46:53 PDT 2014


On Thu, Mar 20, 2014 at 3:29 PM, Peter Collingbourne <peter at pcc.me.uk> wrote:
>
> On Mon, Mar 17, 2014 at 10:28:52AM -0700, Tom Roeder wrote:
> > On Tue, Feb 25, 2014 at 5:41 PM, Eric Christopher <echristo at gmail.com>wrote:
> >
> > > On Mon, Feb 24, 2014 at 4:33 PM, Tom Roeder <tmroeder at google.com> wrote:
> > > >
> > > > I'm definitely interested in removing the inline asm bits. I'm not
> > > > sure what you mean by a pseudo-plt, though; do you mean hooking into
> > > > the code that generates the Procedure Linkage Table? I really don't
> > > > know much about the LLVM back end, so I'd have to learn how that all
> > > > works in LLVM first.
> > >
> > > Either that or using similar functionality. It's definitely more
> > > complicated on the start than using the inline assembly.
> > >
> > > -eric
> > >
> >
> > I've been digging around in the back end for a bit now, trying to figure
> > out the best way to implement the jump-instruction tables; there's already
> > support for jump tables there, but it's a different kind of jump table than
> > the one I want.
> >
> > One direction that looks promising to me is to add an intrinsic, something
> > like:
> >
> > declare void @llvm.jump.instr.table.entry(i8*, i8*)
> >
> > The first argument would be the original function (the one that gets jumped
> > to in the table), and the second argument is the _JT function declared but
> > not defined by the pass.
> >
> > Then I can add a custom lowering in each supported architecture that would
> > turn this into a labeled jump instruction something like
> >
> >   .globl func_JT
> > func_JT:
> >   jmp func at PLT
> >
> >
> > The CFI pass would add a special function that would consist only of these
> > intrinsics, one for each jump statement needed by the table, and padded to
> > a power of two using another special intrinsic (something like
> > llvm.undefined.instr) that would lower to an undefined instruction (like
> > ud2 in x86).
> >
> > I'd appreciate feedback anyone might have about this proposal.
>
> Creating these intrinsic calls could potentially introduce pessimizations,
> as the midend would consider the functions to be used. Though maybe this
> doesn't matter if the CFI pass is run late.
>
> It also seems sort of distasteful to have a function whose sole purpose is
> to hold metadata about other functions.


The way I've implemented it (see the patch I sent to llvm-commits
yesterday), it's not just metadata: the intrinsic lowers to the
jumptable entry code given above. The CFI pass then generates a
function for each jump table; the function consists solely of these
intrinsic calls.

>
>
> An alternative proposal: introduce a new function attribute named, say,
> 'jumptable', which would cause the backend to emit a jump table entry and
> redirect function references other than calls through the jump table. (Direct
> function calls could call the original function directly, as an optimization.)
>
> The CFI pass could then consist of marking every address-taken function with
> 'jumptable' and introducing the pointer safety checks at call sites.

That's an interesting suggestion. I'll look into it.



More information about the llvm-dev mailing list