Re: [PATCH] Vtable pointer verification (corruption/attach detection -- new feature
On 02/01/2013 12:42 AM, Caroline Tice wrote: If this data could be emitted in a declarative fashion, it might be possible to emit it by default, in a separate ELF section. This way, it is always there when needed, and it wouldn't have any performance impact if not used. That might be possible; it would need to be carefully organized though. If is not enough to have a list of all vtable addresses; we need to know, for each virtual class (where by virtual class I mean a class for which a vtable might be generated) the set of vtables that is is legal for an object of that class to point to (i.e. for a base class, it can point to its own vtable or to the vtable of any of its descendants in the inheritance hierarchy). At present, you emit calls to the __VLTRegisterPair() function to implement the registration, correct? I wonder if it's possible to list the arguments to the calls instead (possibly in such a way that no relocations are needed). Initialization for verification mode would pick up this data, performing the registration. Outside verification mode, this data would just be ignored (and no ELF constructor needs to be executed). C++ virtual method calls are efficient, but they have their problems. The vtable needs relocation (contributing to startup cost), and we have the fragile base class problem (which severely constrains the evolution of separately-compiled base classes). Assuming that we need the vtable check and it has non-trivial cost, it might make sense to revamp C++ virtual method dispatch altogether, addressing both security and modularity issues. That might be best, but we don't have the authority to unilaterally make a change of this magnitude to the standard. ;-) This would only affect the cross-vendor C++ ABI, not the standard itself. -- Florian Weimer / Red Hat Product Security Team
Re: [PATCH] Vtable pointer verification (corruption/attach detection -- new feature
cmt...@google.com On Wed, Jan 30, 2013 at 2:09 AM, Florian Weimer wrote: > On 11/01/2012 09:07 PM, Caroline Tice wrote: >> >> We have been developing a new security hardening feature for GCC that >> is designed to detect and handle (during program execution) when a >> vtable pointer that is about to be used for a virtual function call is >> not a valid vtable pointer for that call (i.e. it has become >> corrupted, possibly due to a hacker attack). We gave a presentation >> on this work at the Gnu Tools Cauldron in Prague last July. We now >> have the implementation fully working and are submitting this patch >> for review. We would like to get this into the next release of GCC if >> possible. > > > Thanks for posting this collection of interesting patches. > > As far as I understand it, this changes ABI in the sense that every object > file needs to contain the constructors that register the vtables, otherwise > verification will later fail. Yes. > If this data could be emitted in a > declarative fashion, it might be possible to emit it by default, in a > separate ELF section. This way, it is always there when needed, and it > wouldn't have any performance impact if not used. That might be possible; it would need to be carefully organized though. If is not enough to have a list of all vtable addresses; we need to know, for each virtual class (where by virtual class I mean a class for which a vtable might be generated) the set of vtables that is is legal for an object of that class to point to (i.e. for a base class, it can point to its own vtable or to the vtable of any of its descendants in the inheritance hierarchy). > > I didn't look at the actual permitted-vtable set lookup in detail. How > expensive is it? The set up is expected to be somewhat expensive, although we are trying to make it as efficient as possible. We are in the process of gathering performance data. > C++ virtual method calls are efficient, but they have > their problems. The vtable needs relocation (contributing to startup cost), > and we have the fragile base class problem (which severely constrains the > evolution of separately-compiled base classes). Assuming that we need the > vtable check and it has non-trivial cost, it might make sense to revamp C++ > virtual method dispatch altogether, addressing both security and modularity > issues. That might be best, but we don't have the authority to unilaterally make a change of this magnitude to the standard. ;-) > > (Yes, I understand these two paragraphs go off in entirely different > directions. 8-) > Let me know if you have any more questions, or if you would like any further clarifications. -- Caroline Tice cmt...@google.com > -- > Florian Weimer / Red Hat Product Security Team
Re: [PATCH] Vtable pointer verification (corruption/attach detection -- new feature
On 11/01/2012 09:07 PM, Caroline Tice wrote: We have been developing a new security hardening feature for GCC that is designed to detect and handle (during program execution) when a vtable pointer that is about to be used for a virtual function call is not a valid vtable pointer for that call (i.e. it has become corrupted, possibly due to a hacker attack). We gave a presentation on this work at the Gnu Tools Cauldron in Prague last July. We now have the implementation fully working and are submitting this patch for review. We would like to get this into the next release of GCC if possible. Thanks for posting this collection of interesting patches. As far as I understand it, this changes ABI in the sense that every object file needs to contain the constructors that register the vtables, otherwise verification will later fail. If this data could be emitted in a declarative fashion, it might be possible to emit it by default, in a separate ELF section. This way, it is always there when needed, and it wouldn't have any performance impact if not used. I didn't look at the actual permitted-vtable set lookup in detail. How expensive is it? C++ virtual method calls are efficient, but they have their problems. The vtable needs relocation (contributing to startup cost), and we have the fragile base class problem (which severely constrains the evolution of separately-compiled base classes). Assuming that we need the vtable check and it has non-trivial cost, it might make sense to revamp C++ virtual method dispatch altogether, addressing both security and modularity issues. (Yes, I understand these two paragraphs go off in entirely different directions. 8-) -- Florian Weimer / Red Hat Product Security Team
Re: [PATCH] Vtable pointer verification (corruption/attach detection -- new feature
Can you split the patch into two parts? One for runtime and and one for GCC ? Please also use -up option in the diff command to generate the patch file. thanks, David On Thu, Nov 1, 2012 at 1:07 PM, Caroline Tice wrote: > We have been developing a new security hardening feature for GCC that > is designed to detect and handle (during program execution) when a > vtable pointer that is about to be used for a virtual function call is > not a valid vtable pointer for that call (i.e. it has become > corrupted, possibly due to a hacker attack). We gave a presentation > on this work at the Gnu Tools Cauldron in Prague last July. We now > have the implementation fully working and are submitting this patch > for review. We would like to get this into the next release of GCC if > possible. > > The general idea is to collect class hierarchy and vtable pointer data > while parsing the classes, then use this data to generate (at runtime) > sets of valid vtable pointers, one for each class. We also find every > virtual function call and insert a verification call before the > virtual function call. The verification call takes the set of valid > vtable pointers for the declared class of the object, and the actual > vtable pointer in the object. If the vtable pointer in the object is > in the set of valid vtable pointers for the object, then verification > succeeds and the virtual call is allowed. Otherwise verification > fails and the program aborts. > > We have a written a more detailed design document, which I am also > attaching to this email (GCCVtableSecurityHardeningProposal.txt). > > The implementation can be divided into roughly two parts: > modifications to the main gcc compiler, for things that happen at > compile time (collecting the class hierarchy & vtable information; > generating the runtime calls to build the data sets from this data; > inserting calls to the verification function); and modifications to > the runtime, i.e. functions that go into libstdc++ for building the > data sets, for doing the verification against the data sets, for > protecting the memory where the data sets reside, etc.). > > Please let me know if there is any more information you need, or if > you have any questions about this patch. > > -- Caroline Tice > cmt...@google.com > > libstdc++/ChangeLog > > 2012-11-01 Caroline Tice > > * src/Makefile.am: Add libvtv___la_LIBDD definition; update CXXLINK > to search in libvtv___la_LIBADD and to link in libvtv_init. > * src/Makefile.in: Regenerate. > * libsupc++/Makefile.am: Add libvtv_init.la and libvtv_stubs.la to > toolexeclib_LTLIBRARIES. Add vtv_rts.cc, vtv_malloc.cc and > vtv_utils.cc to sources. Define vtv_init_sources and > vtv_stubs_sources. Also define libvtv_init_la_SOURCES and > libvtv_stubs_la_sources. > * libsupc++/Makefile.in: Regenerate. > * libsupc++/vtv_rts.cc: New file. > * libsupc++/vtv_malloc.h: New file. > * libsupc++/vtv_rts.h: New file. > * libsupc++/vtv_fail.h: New file. > * libsupc++/vtv_set.h: New file. > * libsupc++/vtv_stubs.cc: New file. > * libsupc++/vtv_utils.cc: New file. > * libcupc++/vtv_utils.h: New file. > * libsupc++/vtv_init.cc: New file. > * libsupc++/vtv_malloc.cc: New file. > * config/abi/pre/gnu.ver (GLIBCXX_3.4.18): Add vtable verification > functions and vtable map variables to library export list. > > gcc/ChangeLog: > > 2012-11-01 Caroline Tice > > * tree.h (save_vtable_map_decl): New function decl. > * tree-pass.h (pass_vtable_verify): New pass declaration. > * cp/init.c (build_vtbl_address): Remove 'static' qualifier from > function declaration and definition. > * cp/class.c (finish_struct_1): Add call to vtv_save_class_info, > if the vtable verify flag is set. > * cp/Make-lang.in: Add vtable-class-hierarchy.o to list of object > files. Add definition for building vtable-class-hierarchy.o. > * cp/pt.c (mark_class_instantiated): Add call to vtv_save_class_info > if the vtable verify flag is set. > * cp/decl2 (start_objects): Remove 'static' qualifier from function > declaratin and definition. Add new paramater, 'extra_name'. Change > 'type' var from char array to char *. Call xmalloc & free for 'type'. > Add 'extra_name' to 'type' string. > (finish_objects): Remove 'static' qualifier from function declaration > and definition. Change return type from void to tree. Make function > return early if we're doing vtable verification and the function is > a vtable verification constructor init function. Make this function > return 'fn'. > (generate_ctor_or_dtor_function): Add third argument to calls to > start_objects. > (cp_write_global_declarations): Add calls to vtv_recover_class_