Hi! On Wed, Aug 21, 2013 at 04:43:13PM +0200, Stephen Röttger wrote: > Approach: > The basic idea of the thesis is to record all addresses that are > assigned to a function pointer variable at some place in the program (or > in one of the shared libraries) and if a function pointer is called, > verify that the address has been recorded previously. Thus, if an > attacker overwrites the fp variable with either the address of system() > or of a stack pivoting gadget, the fp call will fail, since these > adresses have never been assigned to a function pointer in the program. > The security of the approach relies on the assumption that no function > that can be abused for malicious purposes is ever assigned to a function > pointer, but this requirement will be weakened under future work. > > How this works: > The compiler, GCC in my PoC, will register all assignments of function > pointer variables in the source code and will create a global variable > for the assigned function, which is initialized to the function's > address. Then, it replaces the address of the function in the assignment > with the address of the newly created variable: > fp f = &printf; > becomes: > printf_var = &printf; > ... > fp f = &printf_var; > Further, a global constructor is created that is run before the main > function of the program or before the shared library is loaded. This > constructor allocates a memory area where it stores the address of each > fp address previously registered. The created global variable is then > overwritten to point to the new memory area instead. Finally, the memory > area is mapped read only. Also, the variable where the address of this > area is stored has to be in read only memory as well to prevent > malicious overwrites. Putting it all together, the memory layout looks > like this: > <read only> > +-------+ +------------+ +------------------+ +----------+ > | fp f | -> | printf_var | -> | protected memory | -> | printf() | > +-------+ +------------+ +------------------+ +----------+ > Additional instructions are emitted by the compiler before function > pointer calls. They will verify that the global variable (printf_var) > points to the protected memory region, from which it extracts the real > function pointer to be called. If an attacker is able to overwrite > either the function pointer or the global variable, he will only be able > to execute functions contained in the protected memory area (which he > can't overwrite since it is mapped read only during normal execution).
Thanks for doing research in this area! :) Your approach seems to have some slight similarities with -fvtable-verify: <http://gcc.gnu.org/ml/gcc-patches/2012-11/txt00001.txt> Maybe some code sharing could be achieved? Greetings, Hannes