Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 21 Aug 2013 23:20:02 +0200
From: Hannes Frederic Sowa <hannes@...essinduktion.org>
To: oss-security@...ts.openwall.com
Cc: gcc@....gnu.org
Subject: Re: PoC: Function Pointer Protection in C Programs

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

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.