On Tue, Feb 17, 2015 at 07:00:14PM -0800, Chandler Carruth wrote:> On Tue, Feb 17, 2015 at 12:35 PM, Peter Collingbourne <peter at pcc.me.uk> > wrote: > > > Hi, > > > > In http://reviews.llvm.org/D7424 we've been discussing whether to insert > > control flow integrity checks in Clang or LLVM. The main challenge is that > > the checks need something like a string associated with each call, and > > there's currently no stable way to ensure that the string stays with the > > call. > > > > The current version of the patch does the checks with an intrinsic, but > > there's a concern that this may interfere with devirtualization. > > > > Does anyone have any opinions besides what's been discussed on the review > > thread? > > > > My primary concern is that I would very much like the CFI implementation to > be truly generic for indirect function calls rather than specific to type > hierarchies. > > Is the issue that for virtual calls there is a dramatically cheaper way to > structure the CFI implementation than there is for fully general indirect > calls?The main problem with a design that is fully generic to indirect calls is a lack of precision. If we design our checks independent of the type hierarchy we could permit virtual calls to a function of the wrong type if the parameter/return types would otherwise match. See also [1] which contains some discussion of precision. There are also ancillary performance benefits of this design. For example, if we lay out the type information near the virtual tables we can in some cases avoid an additional cache miss. Thanks, -- Peter [1] http://www.pcc.me.uk/~peter/acad/usenix14.pdf
On Tue, Feb 17, 2015 at 7:43 PM, Peter Collingbourne <peter at pcc.me.uk> wrote:> > My primary concern is that I would very much like the CFI implementation > to > > be truly generic for indirect function calls rather than specific to type > > hierarchies. > > > > Is the issue that for virtual calls there is a dramatically cheaper way > to > > structure the CFI implementation than there is for fully general indirect > > calls? > > The main problem with a design that is fully generic to indirect calls > is a lack of precision. If we design our checks independent of the type > hierarchy we could permit virtual calls to a function of the wrong type if > the parameter/return types would otherwise match. See also [1] which > contains > some discussion of precision. >This is helpful information, and clarifies a miscommunication. =] My hope would be that we could implement the checks generically, but provide constraints from the frontend to further constrain the correct target set. Does that make sense at all? Maybe to put it another way, if I have some other language than C++ which provides a different language-based constraint on the set of possible targets for an indirect call, it would be nice for both Clang and that other language frontend to encode generic target constraints and then a common check implementation to kick in to implement them. And then the check mechanism could be *completely* generic in the case of fully general indirect calls.> > There are also ancillary performance benefits of this design. For example, > if we lay out the type information near the virtual tables we can in some > cases avoid an additional cache miss.That does seem quite nice to preserve if possible. Is it possible to use a hint to get this? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150217/0d7d1c15/attachment.html>
On Tue, Feb 17, 2015 at 08:02:32PM -0800, Chandler Carruth wrote:> On Tue, Feb 17, 2015 at 7:43 PM, Peter Collingbourne <peter at pcc.me.uk> > wrote: > > > > My primary concern is that I would very much like the CFI implementation > > to > > > be truly generic for indirect function calls rather than specific to type > > > hierarchies. > > > > > > Is the issue that for virtual calls there is a dramatically cheaper way > > to > > > structure the CFI implementation than there is for fully general indirect > > > calls? > > > > The main problem with a design that is fully generic to indirect calls > > is a lack of precision. If we design our checks independent of the type > > hierarchy we could permit virtual calls to a function of the wrong type if > > the parameter/return types would otherwise match. See also [1] which > > contains > > some discussion of precision. > > > > This is helpful information, and clarifies a miscommunication. =] > > My hope would be that we could implement the checks generically, but > provide constraints from the frontend to further constrain the correct > target set. Does that make sense at all? > > Maybe to put it another way, if I have some other language than C++ which > provides a different language-based constraint on the set of possible > targets for an indirect call, it would be nice for both Clang and that > other language frontend to encode generic target constraints and then a > common check implementation to kick in to implement them. And then the > check mechanism could be *completely* generic in the case of fully general > indirect calls.I would be wary of trying to be too generic up front. The two fundamental things we might want to check are properties of pointers into data (for virtual calls) and of pointers into code (for indirect calls through function pointers), and these may very well call for different types of checks. For example, we may well find that the best way to check indirect calls through function pointers is to encode and check for specific instructions in the function body as done in [1], but we shouldn't need to waste space on encoding the instructions in functions called via virtual tables. Also keep in mind that other languages have vtable-like things as well (witness Go interfaces, Haskell type classes and Rust traits) and I do think it would be feasible to implement checks for these features in terms of the same primitives we're introducing here for C++ vtables. Thanks, -- Peter [1] http://research.microsoft.com/pubs/69217/ccs05-cfi.pdf