hashtable: silence -fsanitize=address warning for `hashlittle()` function
authorFrancis Deslauriers <francis.deslauriers@efficios.com>
Fri, 4 Dec 2020 18:47:32 +0000 (13:47 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 4 Jan 2021 22:46:24 +0000 (17:46 -0500)
Issue
=====
The code of this function triggers the following heap-buffer-overflow
warning when compiled with `-fsanitize=address` in specific situation:

  ==247225==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000001310 at pc 0x5559db6c575a bp 0x7f193e6faeb0 sp 0x7f193e6faea0
  READ of size 4 at 0x602000001310 thread T4 (Notification)
      #0 0x5559db6c5759 in hashlittle /home/frdeso/projets/lttng/tools/src/common/hashtable/utils.c:315
      #1 0x5559db6c6df4 in hash_key_str /home/frdeso/projets/lttng/tools/src/common/hashtable/utils.c:490
      #2 0x5559db5e3282 in hash_trigger_by_name_uid /home/frdeso/projets/lttng/tools/src/bin/lttng-sessiond/notification-thread-events.c:378
      #3 0x5559db5ecbe3 in trigger_name_taken /home/frdeso/projets/lttng/tools/src/bin/lttng-sessiond/notification-thread-events.c:2333
      #4 0x5559db5ecd7c in generate_trigger_name /home/frdeso/projets/lttng/tools/src/bin/lttng-sessiond/notification-thread-events.c:2362
      #5 0x5559db5ed6e0 in handle_notification_thread_command_register_trigger /home/frdeso/projets/lttng/tools/src/bin/lttng-sessiond/notification-thread-events.c:2491
      #6 0x5559db5ef967 in handle_notification_thread_command /home/frdeso/projets/lttng/tools/src/bin/lttng-sessiond/notification-thread-events.c:2927
      #7 0x5559db5ddbb7 in thread_notification /home/frdeso/projets/lttng/tools/src/bin/lttng-sessiond/notification-thread.c:693
      #8 0x5559db60e56d in launch_thread /home/frdeso/projets/lttng/tools/src/bin/lttng-sessiond/thread.c:66
      #9 0x7f19456ec608 in start_thread /build/glibc-ZN95T4/glibc-2.31/nptl/pthread_create.c:477
      #10 0x7f1945602292 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x122292)

Given that the `k` pointer used in this loop is a `uint32_t *` we might
read bytes outside of the allocated key if the key is less than 4 bytes
long. As the comment about Valgrind explains, this is not a real problem
because memory protections are typically word bounded.

I tried to use the `__SANITIZE_ADDRESS__` define to select the
Valgrind implementation of this code when building with AddressSanitizer
but that still triggers the same head-buffer-overflow warning.

Why wasn't that a problem before?
=======================================
The trigger feature will use small default names like "T0".

Workaround
==========
Exclude this function from the sanitizing using the compiler attribute
"no_sanitize_address".

Drawback
========
This removes our sanitizing coverage for this function.

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I82d0d3539916ed889faa93871f9b700064f2c52a

src/common/hashtable/utils.c
src/common/macros.h

index 2d027bae0b9cc2350ea69337ea3412dd5727d79d..2c41e6c65f4060f31439640cec8c8c6d62b724c1 100644 (file)
@@ -264,7 +264,9 @@ static void __attribute__((unused)) hashword2(const uint32_t *k, size_t length,
  * Use for hash table lookup, or anything where one collision in 2^^32 is
  * acceptable.  Do NOT use for cryptographic purposes.
  */
-static uint32_t __attribute__((unused)) hashlittle(const void *key,
+LTTNG_NO_SANITIZE_ADDRESS
+__attribute__((unused))
+static uint32_t hashlittle(const void *key,
                size_t length, uint32_t initval)
 {
        uint32_t a,b,c;
index cce09a6cbb66b0474d25dabcf34a43e3728f71ef..e28250f7ed20a7892600c161f6b0921ff10424d3 100644 (file)
@@ -77,6 +77,14 @@ void *zmalloc(size_t len)
 #define LTTNG_PACKED __attribute__((__packed__))
 #endif
 
+#ifndef LTTNG_NO_SANITIZE_ADDRESS
+#if defined(__clang__) || defined (__GNUC__)
+#define LTTNG_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
+#else
+#define LTTNG_NO_SANITIZE_ADDRESS
+#endif
+#endif
+
 #define is_signed(type) (((type) (-1)) < 0)
 
 /*
This page took 0.035292 seconds and 4 git commands to generate.