diff options
| author | Nick Kralevich <nnk@google.com> | 2015-08-22 14:27:03 -0700 |
|---|---|---|
| committer | Nick Kralevich <nnk@google.com> | 2015-08-24 15:52:22 +0000 |
| commit | 1f286989986a384e34d9de1acf8899439506695a (patch) | |
| tree | ca15d9ff0bce7642a7b479002867cac5d0063b15 | |
| parent | 3b94cef1b75893f98ad3011a09582405bb32baf4 (diff) | |
| download | system_core-1f286989986a384e34d9de1acf8899439506695a.tar.gz system_core-1f286989986a384e34d9de1acf8899439506695a.tar.bz2 system_core-1f286989986a384e34d9de1acf8899439506695a.zip | |
libutils: cleanups for -fsanitize=integer
* Hashing functions rely on integer overflow behavior.
Mark those functions as safe.
* abort() if a passed in size_t value is greater than
UINT32_MAX. This can occur on 64 bit builds where size_t
is larger than uint32_t.
* Special case the index lookup for an empty sorted vector.
Without the special case, size() == 0, and size()-1 underflows.
Change-Id: I343a14b589fc8f0d221c1998ae5d6f0b9e2781f8
| -rw-r--r-- | include/utils/JenkinsHash.h | 3 | ||||
| -rw-r--r-- | libutils/JenkinsHash.cpp | 10 | ||||
| -rw-r--r-- | libutils/VectorImpl.cpp | 4 |
3 files changed, 17 insertions, 0 deletions
diff --git a/include/utils/JenkinsHash.h b/include/utils/JenkinsHash.h index 7da5dbd6a..027c10c7e 100644 --- a/include/utils/JenkinsHash.h +++ b/include/utils/JenkinsHash.h @@ -29,6 +29,9 @@ namespace android { /* The Jenkins hash of a sequence of 32 bit words A, B, C is: * Whiten(Mix(Mix(Mix(0, A), B), C)) */ +#ifdef __clang__ +__attribute__((no_sanitize("integer"))) +#endif inline uint32_t JenkinsHashMix(uint32_t hash, uint32_t data) { hash += data; hash += (hash << 10); diff --git a/libutils/JenkinsHash.cpp b/libutils/JenkinsHash.cpp index 52c9bb7df..ff5d252a4 100644 --- a/libutils/JenkinsHash.cpp +++ b/libutils/JenkinsHash.cpp @@ -19,10 +19,14 @@ * should still be quite good. **/ +#include <stdlib.h> #include <utils/JenkinsHash.h> namespace android { +#ifdef __clang__ +__attribute__((no_sanitize("integer"))) +#endif hash_t JenkinsHashWhiten(uint32_t hash) { hash += (hash << 3); hash ^= (hash >> 11); @@ -31,6 +35,9 @@ hash_t JenkinsHashWhiten(uint32_t hash) { } uint32_t JenkinsHashMixBytes(uint32_t hash, const uint8_t* bytes, size_t size) { + if (size > UINT32_MAX) { + abort(); + } hash = JenkinsHashMix(hash, (uint32_t)size); size_t i; for (i = 0; i < (size & -4); i += 4) { @@ -47,6 +54,9 @@ uint32_t JenkinsHashMixBytes(uint32_t hash, const uint8_t* bytes, size_t size) { } uint32_t JenkinsHashMixShorts(uint32_t hash, const uint16_t* shorts, size_t size) { + if (size > UINT32_MAX) { + abort(); + } hash = JenkinsHashMix(hash, (uint32_t)size); size_t i; for (i = 0; i < (size & -2); i += 2) { diff --git a/libutils/VectorImpl.cpp b/libutils/VectorImpl.cpp index 30ca6635e..bdb54b14a 100644 --- a/libutils/VectorImpl.cpp +++ b/libutils/VectorImpl.cpp @@ -551,6 +551,10 @@ size_t SortedVectorImpl::orderOf(const void* item) const ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const { + if (order) *order = 0; + if (isEmpty()) { + return NAME_NOT_FOUND; + } // binary search ssize_t err = NAME_NOT_FOUND; ssize_t l = 0; |
