This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: RFC: GCC plugin to find encrypted function pointer calls in glibc
- From: Aldy Hernandez <aldyh at redhat dot com>
- To: "Carlos O'Donell" <carlos at redhat dot com>, libc-alpha at sourceware dot org, Florian Weimer <fweimer at redhat dot com>
- Date: Mon, 2 May 2016 08:02:35 -0400
- Subject: Re: RFC: GCC plugin to find encrypted function pointer calls in glibc
- Authentication-results: sourceware.org; auth=none
- References: <57233606 dot 7050205 at redhat dot com> <57240891 dot 1000308 at redhat dot com>
On 04/29/2016 09:21 PM, Carlos O'Donell wrote:
You can build glibc with gcc 4.7 or newer.
(1) static inline wrapper with function attribute:
For a representative set of architectures, say x86_64, i686, ppc64,
s390x, aarch64, and arm, does a 4.7 or newer compiler do as good a
job with a static inline function as it does with the macro that
evaluates to a bare assembly?
I grabbed the relevant bits from various glibc backends (x86_64, ppc64,
and arm) and made a testcase that would work on all three architectures.
All we need to verify is that the code generated for
using_original_macro_demangler() and using_new_inline_demangler() is
exactly the same for all three architectures. I have visually verified
that this is so.
It looks like all other architectures are variants of the same pattern
(inline asm or some boiler plate code looking at a global that may be in
a TLS variable), so I didn't bother.
As you can see, what I propose is something as simple as:
#define OLD_MACRO_PTR_DEMANGLE(var) asm("magic")
static inline uintptr_t
new_ptr_demangle (uintptr_t var)
{
OLD_MACRO_PTR_DEMANGLE (var);
return var;
}
#define PTR_DEMANGLE(var) \
var = (typeof(var)) new_ptr_demangle ((uintptr_t) var)
Do y'all agree? Can we use inline functions wrapping the asm's and tag
an attribute on the function?
Aldy
/* Testcase to compare pointer demangling code on various
architectures. */
typedef struct
{
int blah1;
int blah2;
unsigned int pointer_guard;
int blah3;
} tcbhead_t;
#ifdef __x86_64__
typedef unsigned long long int uintptr_t;
#define LP_SIZE "8"
# define PTR_DEMANGLE(var) asm ("ror $2*" LP_SIZE "+1, %0\n" \
"xor %%fs:%c2, %0" \
: "=r" (var) \
: "0" (var), \
"i" (__builtin_offsetof (tcbhead_t, \
pointer_guard)))
#elif defined __powerpc64__
typedef unsigned long long int uintptr_t;
register void *__thread_register __asm__ ("r13");
# define TLS_TCB_OFFSET 0x7000
# define THREAD_GET_POINTER_GUARD() \
(((tcbhead_t *) ((char *) __thread_register
\
- TLS_TCB_OFFSET))[-1].pointer_guard)
# define PTR_MANGLE(var) \
(var) = (__typeof (var)) ((uintptr_t) (var) ^
THREAD_GET_POINTER_GUARD ())
# define PTR_DEMANGLE(var) PTR_MANGLE (var)
#elif defined __arm__
typedef unsigned long int uintptr_t;
# define attribute_hidden __attribute__ ((visibility ("hidden")))
#define attribute_relro __attribute__ ((section (".data.rel.ro")))
/* Only exported for architectures that don't store the pointer guard
value in thread local area. */
uintptr_t __pointer_chk_guard
attribute_relro attribute_hidden __attribute__ ((nocommon));
# define PTR_MANGLE(var) \
(var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
# define PTR_DEMANGLE(var) PTR_MANGLE (var)
#else
#error "architecture not supported"
#endif
static inline uintptr_t
ptr_demangle (uintptr_t var)
{
PTR_DEMANGLE (var);
return var;
}
#define PTR_DEMANGLE2(var) \
var = (typeof(var)) ptr_demangle ((uintptr_t) var)
typedef int (*callback) (void);
void
using_original_macro_demangler (callback cb)
{
PTR_DEMANGLE (cb);
cb();
}
void
using_new_inline_demangler (callback cb)
{
PTR_DEMANGLE2 (cb);
cb();
}