Alternative libio vtable hardening approach

Florian Weimer fweimer@redhat.com
Fri Jun 3 09:44:00 GMT 2016


On 06/03/2016 11:34 AM, Pedro Alves wrote:
> On 05/31/2016 02:07 PM, Florian Weimer wrote:
>> I have implemented a completely different approach to vtable hardening.
>>
>> The basic idea is to put all libc vtables into a single array, and then
>> check whether the vtable pointer is within that array.
>
> Instead of a single array, how about instead putting all the vtables in
> the same section with __attribute__ section.  Something like:
>
> + #define __vtable __attribute__ ((section("vtables")))
>
> - const struct _IO_jump_t _IO_file_jumps_mmap =
> + const struct _IO_jump_t __vtable _IO_file_jumps_mmap =
>   ...
>
> and then check whether the vtable pointer is within that section,
> with __start_vtables, __end_vtables:
>
> static inline const struct _IO_jump_t *
> IO_validate_vtable (const struct _IO_jump_t *vtable)
> {
>   extern char __start_vtables[];
>   extern char __end_vtables[];
>
>   if (!__glibc_likely ((long) __start_vtables <= vtable
> 		       && vtable < (long) __end_vtables))
>     IO_vtable_check ();
>   return vtable;
> }
>
> That'd avoid having to have a central place that knows about all
> the vtables.   It'd probably make the patch smaller too, as
> side effect.

This will need an additional substraction in the validation code because 
there is no relocation to express the different between two pointers, 
even though this value is a link-time constant.  The statically sized 
array makes the difference a constant, avoiding this problem.

(GCC currently does not perform this optimization for pointer 
differences, but it's easy enough to do it manually.)

Thanks,
Florian



More information about the Libc-alpha mailing list