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

[PATCH v10 4/10] libs/guest: use Valgrind or sanitizers to detect various buffer overflows



Previously this was done as buffers were allocated separately.

Signed-off-by: Frediano Ziglio <frediano.ziglio@xxxxxxxxxx>
---
Changes since v9:
- add support for sanitizers also;
- remove some unneeded check buffers.
---
 tools/config.h.in               |  6 ++++
 tools/configure                 | 12 +++++++
 tools/configure.ac              |  3 +-
 tools/libs/ctrl/xc_private.h    | 61 +++++++++++++++++++++++++++++++--
 tools/libs/guest/xg_sr_common.h |  6 ++++
 tools/libs/guest/xg_sr_save.c   | 11 ++++++
 6 files changed, 96 insertions(+), 3 deletions(-)

diff --git a/tools/config.h.in b/tools/config.h.in
index ed0042018d..d51816453b 100644
--- a/tools/config.h.in
+++ b/tools/config.h.in
@@ -48,6 +48,12 @@
 /* ROMBIOS enabled */
 #undef HAVE_ROMBIOS
 
+/* Define to 1 if you have the <sanitizer/asan_interface.h> header file. */
+#undef HAVE_SANITIZER_ASAN_INTERFACE_H
+
+/* Define to 1 if you have the <sanitizer/msan_interface.h> header file. */
+#undef HAVE_SANITIZER_MSAN_INTERFACE_H
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
diff --git a/tools/configure b/tools/configure
index cd989925ed..94e630665f 100755
--- a/tools/configure
+++ b/tools/configure
@@ -10203,6 +10203,18 @@ then :
   printf "%s\n" "#define HAVE_UTMP_H 1" >>confdefs.h
 
 fi
+ac_fn_c_check_header_compile "$LINENO" "sanitizer/asan_interface.h" 
"ac_cv_header_sanitizer_asan_interface_h" "$ac_includes_default"
+if test "x$ac_cv_header_sanitizer_asan_interface_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SANITIZER_ASAN_INTERFACE_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "sanitizer/msan_interface.h" 
"ac_cv_header_sanitizer_msan_interface_h" "$ac_includes_default"
+if test "x$ac_cv_header_sanitizer_msan_interface_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SANITIZER_MSAN_INTERFACE_H 1" >>confdefs.h
+
+fi
 
 
 # Check for libnl3 >=3.2.8. If present enable remus network buffering.
diff --git a/tools/configure.ac b/tools/configure.ac
index 74b9f56025..5346ff6129 100644
--- a/tools/configure.ac
+++ b/tools/configure.ac
@@ -454,7 +454,8 @@ AC_CHECK_DECLS([fdt_property_u32],,,[#include <libfdt.h>])
 esac
 
 # Checks for header files.
-AC_CHECK_HEADERS([yajl/yajl_version.h sys/eventfd.h valgrind/memcheck.h 
utmp.h])
+AC_CHECK_HEADERS([yajl/yajl_version.h sys/eventfd.h valgrind/memcheck.h \
+                  utmp.h sanitizer/asan_interface.h 
sanitizer/msan_interface.h])
 
 # Check for libnl3 >=3.2.8. If present enable remus network buffering.
 PKG_CHECK_MODULES(LIBNL3, [libnl-3.0 >= 3.2.8 libnl-route-3.0 >= 3.2.8],
diff --git a/tools/libs/ctrl/xc_private.h b/tools/libs/ctrl/xc_private.h
index 8a325c17b0..7803192599 100644
--- a/tools/libs/ctrl/xc_private.h
+++ b/tools/libs/ctrl/xc_private.h
@@ -42,13 +42,70 @@
 
 #include <xen-tools/common-macros.h>
 
-#if defined(HAVE_VALGRIND_MEMCHECK_H) && !defined(NDEBUG) && 
!defined(__MINIOS__)
+#undef XEN_USE_MEM_NOACCESS
+#if !defined(NDEBUG) && !defined(__MINIOS__)
+
+#if !defined(__has_feature)
+#define __has_feature(x) 0
+#endif
+
+#if defined(HAVE_SANITIZER_ASAN_INTERFACE_H) && \
+    (__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__))
+#include <sanitizer/asan_interface.h>
+#define XEN_USE_MEM_NOACCESS 1
+#elif defined(HAVE_SANITIZER_MSAN_INTERFACE_H) && \
+    __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+#define XEN_USE_MEM_NOACCESS 1
+#endif
+#if defined(HAVE_VALGRIND_MEMCHECK_H)
 /* Compile in Valgrind client requests? */
 #include <valgrind/memcheck.h>
-#else
+#define XEN_USE_MEM_NOACCESS 1
+#endif
+
+#endif
+
+#if !defined(HAVE_VALGRIND_MEMCHECK_H) || defined(NDEBUG) || 
defined(__MINIOS__)
 #define VALGRIND_MAKE_MEM_UNDEFINED(addr, len) /* addr, len */
 #endif
 
+#if defined(XEN_USE_MEM_NOACCESS)
+#define MEM_NOACCESS_BUFFER(name, size) uint8_t name[size];
+#if defined(HAVE_VALGRIND_MEMCHECK_H)
+#define MEM_NOACCESS_INIT_VALGRIND(field) \
+    VALGRIND_MAKE_MEM_NOACCESS(field, sizeof(field))
+#else
+#define MEM_NOACCESS_INIT_VALGRIND(field)
+#endif
+#if defined(HAVE_SANITIZER_ASAN_INTERFACE_H) && \
+    (__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__))
+#define MEM_NOACCESS_INIT_SANITIZER(field) \
+    ASAN_POISON_MEMORY_REGION(field, sizeof(field))
+#else
+#define MEM_NOACCESS_INIT_SANITIZER(field)
+#endif
+#if defined(HAVE_SANITIZER_MSAN_INTERFACE_H) && \
+    __has_feature(memory_sanitizer)
+#define MEM_UNDEFINED_INIT_SANITIZER(field) \
+    __msan_poison(field, sizeof(field))
+#else
+#define MEM_UNDEFINED_INIT_SANITIZER(field)
+#endif
+#define MEM_NOACCESS_INIT(field) do { \
+    MEM_NOACCESS_INIT_VALGRIND(field); \
+    MEM_NOACCESS_INIT_SANITIZER(field); \
+} while(0)
+#define MEM_UNDEFINED_INIT(field) do { \
+    VALGRIND_MAKE_MEM_UNDEFINED(field, sizeof(field)); \
+    MEM_UNDEFINED_INIT_SANITIZER(field); \
+} while(0)
+#else
+#define MEM_NOACCESS_BUFFER(name, size)
+#define MEM_NOACCESS_INIT(field) do {} while(0)
+#define MEM_UNDEFINED_INIT(field) do {} while(0)
+#endif
+
 #if defined(__MINIOS__)
 /*
  * MiniOS's libc doesn't know about sys/uio.h or writev().
diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index c07c6db59e..020b1a5272 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -246,11 +246,17 @@ struct xc_sr_context
             struct xc_sr_context_save_buffers
             {
                 xen_pfn_t batch_pfns[MAX_BATCH_SIZE];
+                MEM_NOACCESS_BUFFER(na0, 64);
                 xen_pfn_t mfns[MAX_BATCH_SIZE];
+                MEM_NOACCESS_BUFFER(na1, 64);
                 xen_pfn_t types[MAX_BATCH_SIZE];
+                MEM_NOACCESS_BUFFER(na2, 64);
                 void *local_pages[MAX_BATCH_SIZE];
+                MEM_NOACCESS_BUFFER(na3, 64);
                 struct iovec iov[MAX_BATCH_SIZE + 2]; /* Headers + data. */
+                MEM_NOACCESS_BUFFER(na4, 64);
                 uint64_t rec_pfns[MAX_BATCH_SIZE];
+                MEM_NOACCESS_BUFFER(na5, 64);
                 int errors[MAX_BATCH_SIZE];
             } *buffers;
         } save;
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index 6a77e33a47..96d7e9e2f8 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -123,6 +123,11 @@ static int write_batch(struct xc_sr_context *ctx)
     assert(nr_pfns != 0);
     assert(nr_pfns <= MAX_BATCH_SIZE);
 
+    MEM_UNDEFINED_INIT(ctx->save.buffers->mfns);
+    MEM_UNDEFINED_INIT(ctx->save.buffers->types);
+    MEM_UNDEFINED_INIT(ctx->save.buffers->iov);
+    MEM_UNDEFINED_INIT(ctx->save.buffers->rec_pfns);
+
     iov[0].iov_base = &hdrs;
     iov[0].iov_len = sizeof(hdrs);
 
@@ -783,6 +788,12 @@ static int setup(struct xc_sr_context *ctx)
         errno = ENOMEM;
         goto err;
     }
+    MEM_NOACCESS_INIT(ctx->save.buffers->na0);
+    MEM_NOACCESS_INIT(ctx->save.buffers->na1);
+    MEM_NOACCESS_INIT(ctx->save.buffers->na2);
+    MEM_NOACCESS_INIT(ctx->save.buffers->na3);
+    MEM_NOACCESS_INIT(ctx->save.buffers->na4);
+    MEM_NOACCESS_INIT(ctx->save.buffers->na5);
 
     rc = 0;
 
-- 
2.43.0




 


Rackspace

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