summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Golubev <andrei.golubev@qt.io>2020-10-01 17:28:29 +0200
committerAndrei Golubev <andrei.golubev@qt.io>2020-10-05 09:33:07 +0200
commit3929fd3c56637172d2cb94bcf3130322366a5e75 (patch)
treed170a431dc59d4f9bf02b5ce67e8fe80fd280465
parent623e866d5c5b9e49f827208604c8608f55dbff3f (diff)
Do not use QHash's aeshash() under Clang's sanitizer
aeshash() has a heap-buffer-overflow when the passed in buffer length is less than 16 bytes (and I expect there's a similar issue when we process the tail when length is not divisible by 16). Despite being a real issue, the code has guarding mechanisms to make sure that: 1) no crash happens 2) out-of-range bits are not used in the computation Disabled the usage of aeshash() under Clang's sanitizer similarly to how it was done for GCC (apparently it uses its own preprocessor mechanism). Likely, this will pop up again with MSVC, but I have no clue which defines it uses Task-number: QTBUG-87112 Task-number: QTBUG-86051 Change-Id: I614d7b3082e91c9d16e0441649d6a153b222bd2e Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/tools/qhash.cpp16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 0f7d08e06d..06e211b9a2 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.com>.
** Contact: https://www.qt.io/licensing/
@@ -387,11 +387,23 @@ static uint siphash(const uint8_t *in, uint inlen, const uint seed)
}
#endif
+#if defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_THREAD__) // GCC
+# define QHASH_AES_SANITIZER_BUILD
+#elif QT_HAS_FEATURE(address_sanitizer) || QT_HAS_FEATURE(thread_sanitizer) // Clang
+# define QHASH_AES_SANITIZER_BUILD
+#endif
+// When built with a sanitizer, aeshash() is rightfully reported to have a
+// heap-buffer-overflow issue. However, we consider it to be safe in this
+// specific case and overcome the problem by correctly discarding the
+// out-of-range bits. To allow building the code with sanitizer,
+// QHASH_AES_SANITIZER_BUILD is used to disable aeshash() usage.
#if QT_COMPILER_SUPPORTS_HERE(AES) && QT_COMPILER_SUPPORTS_HERE(SSE4_2) && \
- !(defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_THREAD__))
+ !defined(QHASH_AES_SANITIZER_BUILD)
# define AESHASH
+#undef QHASH_AES_SANITIZER_BUILD
+
QT_FUNCTION_TARGET(AES)
static size_t aeshash(const uchar *p, size_t len, size_t seed) noexcept
{