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

Reply via email to