[LLVMdev] [RFC] Simple control-flow integrity

Peter Collingbourne peter at pcc.me.uk
Thu Mar 20 15:29:48 PDT 2014


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.

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.

Thanks,
-- 
Peter



More information about the llvm-dev mailing list