]> git.eshelyaron.com Git - emacs.git/commitdiff
Make unaligned loads work with sanitization.
authorVibhav Pant <vibhavp@gmail.com>
Wed, 7 Dec 2022 15:26:17 +0000 (20:56 +0530)
committerVibhav Pant <vibhavp@gmail.com>
Wed, 7 Dec 2022 15:26:17 +0000 (20:56 +0530)
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 <sanitizer/common_interface_defs.h>.
* 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
src/fns.c
src/lisp.h

index ec1729120b12142656f7742c535a3a1038d44284..e9bca7eda26c493f53eaa584a096101e51fd8514 100644 (file)
@@ -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],
index d8744c1a4de1a4b30108c029c1f13244fddafd8f..19556bf1fbcaec71e8c469746b9551aa84695791 100644 (file)
--- 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.  */
index 0f70f60d75c7cfb00de6f8d5e3286998983469c0..f466d4b0da59de275933137866a5c201341b6f26 100644 (file)
@@ -5296,6 +5296,22 @@ __lsan_ignore_object (void const *p)
 }
 #endif
 
+#if defined HAVE_SANITIZER_COMMON_INTERFACE_DEFS_H \
+  && defined ADDRESS_SANITIZER
+# include <sanitizer/common_interface_defs.h>
+# 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);