[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] x86emul: rework wrapping of libc functions in test and fuzzing harnesses



commit 6fba45ca3be1c5d46cddb1eaf371d9e69550b244
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Fri Aug 18 15:04:28 2023 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri Aug 18 15:04:28 2023 +0200

    x86emul: rework wrapping of libc functions in test and fuzzing harnesses
    
    Our present approach is working fully behind the compiler's back. This
    was found to not work with LTO. Employ ld's --wrap= option instead. Note
    that while this makes the build work at least with new enough gcc (it
    doesn't with gcc7, for example, due to tool chain side issues afaict),
    according to my testing things still won't work when building the
    fuzzing harness with afl-cc: While with the gcc7 tool chain I see afl-as
    getting invoked, this does not happen with gcc13. Yet without using that
    assembler wrapper the resulting binary will look uninstrumented to
    afl-fuzz.
    
    While checking the resulting binaries I noticed that we've gained uses
    of snprintf() and strstr(), which only just so happen to not cause any
    problems. Add a wrappers for them as well.
    
    Since we don't have any actual uses of v{,sn}printf(), no definitions of
    their wrappers appear (just yet). But I think we want
    __wrap_{,sn}printf() to properly use __real_v{,sn}printf() right away,
    which means we need delarations of the latter.
    
    Reported-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Suggested-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Tested-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 tools/fuzz/x86_instruction_emulator/Makefile |  6 ++-
 tools/tests/x86_emulator/Makefile            |  4 +-
 tools/tests/x86_emulator/wrappers.c          | 55 ++++++++++++++++++++--------
 tools/tests/x86_emulator/x86-emulate.h       | 14 +++----
 4 files changed, 53 insertions(+), 26 deletions(-)

diff --git a/tools/fuzz/x86_instruction_emulator/Makefile 
b/tools/fuzz/x86_instruction_emulator/Makefile
index 0100cfc8ac..1e4c6b37f5 100644
--- a/tools/fuzz/x86_instruction_emulator/Makefile
+++ b/tools/fuzz/x86_instruction_emulator/Makefile
@@ -35,6 +35,8 @@ OBJS := fuzz-emul.o x86-emulate.o
 OBJS += x86_emulate/0f01.o x86_emulate/0fae.o x86_emulate/0fc7.o
 OBJS += x86_emulate/decode.o x86_emulate/fpu.o
 
+WRAPPED = $(shell sed -n 's,^ *WRAP(\([[:alnum:]_]*\));,\1,p' x86-emulate.h)
+
 private.h := x86-emulate.h x86_emulate/x86_emulate.h x86_emulate/private.h
 
 x86-emulate.h: x86_emulate/x86_emulate.h
@@ -51,10 +53,10 @@ x86-insn-fuzzer.a: $(OBJS) cpuid.o
        $(AR) rc $@ $^
 
 afl-harness: afl-harness.o $(OBJS) cpuid.o wrappers.o
-       $(CC) $(CFLAGS) $^ -o $@
+       $(CC) $(CFLAGS) $(addprefix -Wl$(comma)--wrap=,$(WRAPPED)) $^ -o $@
 
 afl-harness-cov: afl-harness-cov.o $(patsubst %.o,%-cov.o,$(OBJS)) cpuid.o 
wrappers.o
-       $(CC) $(CFLAGS) $(GCOV_FLAGS) $^ -o $@
+       $(CC) $(CFLAGS) $(GCOV_FLAGS) $(addprefix 
-Wl$(comma)--wrap=,$(WRAPPED)) $^ -o $@
 
 # Common targets
 .PHONY: all
diff --git a/tools/tests/x86_emulator/Makefile 
b/tools/tests/x86_emulator/Makefile
index 4079412d2e..affabc0277 100644
--- a/tools/tests/x86_emulator/Makefile
+++ b/tools/tests/x86_emulator/Makefile
@@ -259,8 +259,10 @@ OBJS := x86-emulate.o cpuid.o test_x86_emulator.o 
evex-disp8.o predicates.o wrap
 OBJS += x86_emulate/0f01.o x86_emulate/0fae.o x86_emulate/0fc7.o
 OBJS += x86_emulate/blk.o x86_emulate/decode.o x86_emulate/fpu.o 
x86_emulate/util.o
 
+WRAPPED := $(shell sed -n 's,^ *WRAP(\([[:alnum:]_]*\));,\1,p' x86-emulate.h)
+
 $(TARGET): $(OBJS)
-       $(HOSTCC) $(HOSTCFLAGS) -o $@ $^
+       $(HOSTCC) $(HOSTCFLAGS) $(addprefix -Wl$(comma)--wrap=,$(WRAPPED)) -o 
$@ $^
 
 .PHONY: clean
 clean:
diff --git a/tools/tests/x86_emulator/wrappers.c 
b/tools/tests/x86_emulator/wrappers.c
index eba7cc93c5..3829a6f416 100644
--- a/tools/tests/x86_emulator/wrappers.c
+++ b/tools/tests/x86_emulator/wrappers.c
@@ -1,78 +1,103 @@
 #include <stdarg.h>
 
-#define WRAP(x) typeof(x) emul_##x
+#define WRAP(x) typeof(x) __wrap_ ## x, __real_ ## x
 #include "x86-emulate.h"
 
-size_t emul_fwrite(const void *src, size_t sz, size_t n, FILE *f)
+size_t __wrap_fwrite(const void *src, size_t sz, size_t n, FILE *f)
 {
     emul_save_fpu_state();
-    sz = fwrite(src, sz, n, f);
+    sz = __real_fwrite(src, sz, n, f);
     emul_restore_fpu_state();
 
     return sz;
 }
 
-int emul_memcmp(const void *p1, const void *p2, size_t sz)
+int __wrap_memcmp(const void *p1, const void *p2, size_t sz)
 {
     int rc;
 
     emul_save_fpu_state();
-    rc = memcmp(p1, p2, sz);
+    rc = __real_memcmp(p1, p2, sz);
     emul_restore_fpu_state();
 
     return rc;
 }
 
-void *emul_memcpy(void *dst, const void *src, size_t sz)
+void *__wrap_memcpy(void *dst, const void *src, size_t sz)
 {
     emul_save_fpu_state();
-    memcpy(dst, src, sz);
+    __real_memcpy(dst, src, sz);
     emul_restore_fpu_state();
 
     return dst;
 }
 
-void *emul_memset(void *dst, int c, size_t sz)
+void *__wrap_memset(void *dst, int c, size_t sz)
 {
     emul_save_fpu_state();
-    memset(dst, c, sz);
+    __real_memset(dst, c, sz);
     emul_restore_fpu_state();
 
     return dst;
 }
 
-int emul_printf(const char *fmt, ...)
+int __wrap_printf(const char *fmt, ...)
 {
     va_list varg;
     int rc;
 
     emul_save_fpu_state();
     va_start(varg, fmt);
-    rc = vprintf(fmt, varg);
+    rc = __real_vprintf(fmt, varg);
     va_end(varg);
     emul_restore_fpu_state();
 
     return rc;
 }
 
-int emul_putchar(int c)
+int __wrap_putchar(int c)
 {
     int rc;
 
     emul_save_fpu_state();
-    rc = putchar(c);
+    rc = __real_putchar(c);
     emul_restore_fpu_state();
 
     return rc;
 }
 
-int emul_puts(const char *str)
+int __wrap_puts(const char *str)
 {
     int rc;
 
     emul_save_fpu_state();
-    rc = puts(str);
+    rc = __real_puts(str);
     emul_restore_fpu_state();
 
     return rc;
 }
+
+int __wrap_snprintf(char *buf, size_t n, const char *fmt, ...)
+{
+    va_list varg;
+    int rc;
+
+    emul_save_fpu_state();
+    va_start(varg, fmt);
+    rc = __real_vsnprintf(buf, n, fmt, varg);
+    va_end(varg);
+    emul_restore_fpu_state();
+
+    return rc;
+}
+
+char *__wrap_strstr(const char *s1, const char *s2)
+{
+    char *s;
+
+    emul_save_fpu_state();
+    s = __real_strstr(s1, s2);
+    emul_restore_fpu_state();
+
+    return s;
+}
diff --git a/tools/tests/x86_emulator/x86-emulate.h 
b/tools/tests/x86_emulator/x86-emulate.h
index 350d1a0abf..34f0855114 100644
--- a/tools/tests/x86_emulator/x86-emulate.h
+++ b/tools/tests/x86_emulator/x86-emulate.h
@@ -32,9 +32,7 @@
 #ifdef EOF
 # error "Must not include <stdio.h> before x86-emulate.h"
 #endif
-#ifdef WRAP
-# include <stdio.h>
-#endif
+#include <stdio.h>
 
 #include <xen/xen.h>
 
@@ -88,11 +86,7 @@ struct x86_fxsr *get_fpu_save_area(void);
  * around the actual function.
  */
 #ifndef WRAP
-# if 0 /* This only works for explicit calls, not for compiler generated ones. 
*/
-#  define WRAP(x) typeof(x) x asm("emul_" #x)
-# else
-# define WRAP(x) asm(".equ " #x ", emul_" #x)
-# endif
+# define WRAP(x) typeof(x) __wrap_ ## x
 #endif
 
 WRAP(fwrite);
@@ -102,6 +96,10 @@ WRAP(memset);
 WRAP(printf);
 WRAP(putchar);
 WRAP(puts);
+WRAP(snprintf);
+WRAP(strstr);
+WRAP(vprintf);
+WRAP(vsnprintf);
 
 #undef WRAP
 
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.