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