From a4c42e80075f5dcdf21c33bc63b14af981c8a79a Mon Sep 17 00:00:00 2001 From: Islam AbdelRahman Date: Mon, 24 Jul 2017 10:47:19 -0700 Subject: [PATCH] Fix UBSAN issue of passing nullptr to memcmp Summary: As explained in the comments, Sometimes we create Slice(nullptr, 0) in our code base which cause us to do calls like ``` memcmp(nullptr, "abc", 0); ``` That's fine since the len is equal 0, but UBSAN is not happy about it so disable UBSAN for this function and add an assert instead Closes https://github.com/facebook/rocksdb/pull/2616 Differential Revision: D5458326 Pulled By: IslamAbdelRahman fbshipit-source-id: cfca32abe30f7d8f760c9f77ecd9543dfb1170dd --- include/rocksdb/slice.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/rocksdb/slice.h b/include/rocksdb/slice.h index fe8dee00f..d1786dd44 100644 --- a/include/rocksdb/slice.h +++ b/include/rocksdb/slice.h @@ -213,8 +213,18 @@ inline bool operator!=(const Slice& x, const Slice& y) { return !(x == y); } +// UBSAN complain that we pass nullptr to memcmp that's fine since +// we always do that for a string of len = 0 +#ifdef ROCKSDB_UBSAN_RUN +#if defined(__clang__) +__attribute__((__no_sanitize__("undefined"))) +#elif defined(__GNUC__) +__attribute__((__no_sanitize_undefined__)) +#endif +#endif inline int Slice::compare(const Slice& b) const { const size_t min_len = (size_ < b.size_) ? size_ : b.size_; + assert((data_ != nullptr && b.data_ != nullptr) || min_len == 0); int r = memcmp(data_, b.data_, min_len); if (r == 0) { if (size_ < b.size_) r = -1;