This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: GCC plugin to find encrypted function pointer calls in glibc


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();
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]