SWRAP_SYMBOL_ENTRY(syscall);
#endif
};
+#undef SWRAP_SYMBOL_ENTRY
+
+#define SWRAP_SYMBOL_ENTRY(i) \
+ union { \
+ __rtld_default_##i f; \
+ void *obj; \
+ } _rtld_default_##i
+
+#ifdef HAVE_SYSCALL
+typedef bool (*__rtld_default_uid_wrapper_syscall_valid)(long int sysno);
+typedef long int (*__rtld_default_uid_wrapper_syscall_va)(long int sysno, va_list va);
+#endif
+
+struct swrap_rtld_default_symbols {
+#ifdef HAVE_SYSCALL
+ SWRAP_SYMBOL_ENTRY(uid_wrapper_syscall_valid);
+ SWRAP_SYMBOL_ENTRY(uid_wrapper_syscall_va);
+#else
+ uint8_t dummy;
+#endif
+};
+#undef SWRAP_SYMBOL_ENTRY
struct swrap {
struct {
void *socket_handle;
struct swrap_libc_symbols symbols;
} libc;
+
+ struct {
+ struct swrap_rtld_default_symbols symbols;
+ } rtld_default;
};
static struct swrap swrap;
#define swrap_bind_symbol_libsocket(sym_name) \
_swrap_bind_symbol_generic(SWRAP_LIBSOCKET, sym_name)
+#define swrap_bind_symbol_rtld_default_optional(sym_name) do { \
+ swrap.rtld_default.symbols._rtld_default_##sym_name.obj = \
+ dlsym(RTLD_DEFAULT, #sym_name); \
+} while(0);
+
static void swrap_bind_symbol_all(void);
/****************************************************************************
return rc;
}
+
+static bool swrap_uwrap_syscall_valid(long int sysno)
+{
+ swrap_bind_symbol_all();
+
+ if (swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_valid.f == NULL) {
+ return false;
+ }
+
+ return swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_valid.f(
+ sysno);
+}
+
+DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
+static long int swrap_uwrap_syscall_va(long int sysno, va_list va)
+{
+ swrap_bind_symbol_all();
+
+ if (swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_va.f == NULL) {
+ /*
+ * Fallback to libc, if uid_wrapper_syscall_va is not
+ * available.
+ */
+ return libc_vsyscall(sysno, va);
+ }
+
+ return swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_va.f(
+ sysno,
+ va);
+}
#endif /* HAVE_SYSCALL */
/* DO NOT call this function during library initialization! */
swrap_bind_symbol_libsocket(writev);
#ifdef HAVE_SYSCALL
swrap_bind_symbol_libc(syscall);
+ swrap_bind_symbol_rtld_default_optional(uid_wrapper_syscall_valid);
+ swrap_bind_symbol_rtld_default_optional(uid_wrapper_syscall_va);
#endif
}
* we care about...
*/
if (!swrap_is_swrap_related_syscall(sysno)) {
+ /*
+ * We need to give socket_wrapper a
+ * chance to take over...
+ */
+ if (swrap_uwrap_syscall_valid(sysno)) {
+ rc = swrap_uwrap_syscall_va(sysno, va);
+ va_end(va);
+ return rc;
+ }
+
rc = libc_vsyscall(sysno, va);
va_end(va);
return rc;