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
* 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;
#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)
/*