From 7f8aa9db63de147f4196525de99007e1e5c64dfe Mon Sep 17 00:00:00 2001 From: Vibhav Pant Date: Wed, 7 Dec 2022 20:56:17 +0530 Subject: [PATCH] Make unaligned loads work with sanitization. Address sanitizer may miss memory bugs that happen during unaligned loads. To prevent that, compilers may provide additional functions to perform unaligned loads/stores, which allow sanitizer instrumentation to check these accesses too. If the necessary header is available, and AddressSanitizer is enabled, use them. * configure.ac: Add check for . * src/lisp.h (UNALIGNED_LOAD_SIZE) [ADDRESS_SANITIZER]: New macro. If the common sanitizer interface is available and address sanitization is enabled, define it to __sanitizer_unaligned_load(64|32), depending on the word size of the architecture. * src/fns.c [HAVE_FAST_UNALIGNED_ACCESS] (Fstring_lessp): Use 'UNALIGNED_LOAD_SIZE' to perform unaligned loads from the two strings. --- configure.ac | 3 ++- src/fns.c | 9 +++++++-- src/lisp.h | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index ec1729120b1..e9bca7eda26 100644 --- a/configure.ac +++ b/configure.ac @@ -1842,7 +1842,8 @@ AC_CHECK_HEADERS_ONCE( sys/resource.h sys/utsname.h pwd.h utmp.h util.h sanitizer/lsan_interface.h - sanitizer/asan_interface.h]) + sanitizer/asan_interface.h + sanitizer/common_interface_defs.h]) AC_CACHE_CHECK([for ADDR_NO_RANDOMIZE], [emacs_cv_personality_addr_no_randomize], diff --git a/src/fns.c b/src/fns.c index d8744c1a4de..19556bf1fbc 100644 --- a/src/fns.c +++ b/src/fns.c @@ -497,8 +497,13 @@ Symbols are also allowed; their print names are used instead. */) int ws = sizeof (word_t); const word_t *w1 = (const word_t *) SDATA (string1); const word_t *w2 = (const word_t *) SDATA (string2); - while (b < nb - ws + 1 && w1[b / ws] == w2[b / ws]) - b += ws; + while (b < nb - ws + 1) + { + if (UNALIGNED_LOAD_SIZE (w1, b / ws) + != UNALIGNED_LOAD_SIZE (w2, b / ws)) + break; + b += ws; + } } /* Scan forward to the differing byte. */ diff --git a/src/lisp.h b/src/lisp.h index 0f70f60d75c..f466d4b0da5 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -5296,6 +5296,22 @@ __lsan_ignore_object (void const *p) } #endif +#if defined HAVE_SANITIZER_COMMON_INTERFACE_DEFS_H \ + && defined ADDRESS_SANITIZER +# include +# if (SIZE_MAX == UINT64_MAX) +# define UNALIGNED_LOAD_SIZE(a, i) \ + (size_t) __sanitizer_unaligned_load64 ((void *) ((a) + (i))) +# elif (SIZE_MAX == UINT32_MAX) +# define UNALIGNED_LOAD_SIZE(a, i) \ + (size_t) __sanitizer_unaligned_load32 ((void *) ((a) + (i))) +# else +# define UNALIGNED_LOAD_SIZE(a, i) *((a) + (i)) +# endif +#else +# define UNALIGNED_LOAD_SIZE(a, i) *((a) + (i)) +#endif + extern void xputenv (const char *); extern char *egetenv_internal (const char *, ptrdiff_t); -- 2.39.2