From 0484b3b5757594a43c6b646824b44643d2a007de Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Thu, 11 Aug 2016 08:02:06 -0700 Subject: logd: ASAN cleansing A mixture of fixes and cleanup for LogKlog.cpp and friends. - sscanf calls strlen. Check if the string is missing a nul terminator, if it is, do not call sscanf. - replace NULL with nullptr for stronger typechecking. - pass by reference for simpler code. - Use ssize_t where possible to check for negative values. - fix FastCmp to add some validity checking since ASAN reports that callers are not making sure pre-conditions are met. - add fasticmp templates for completeness. - if the buffer is too small to contain a meaningful time, do not call down to log_time::strptime() because it does not limit its accesses to the buffer boundaries, instead stopping at a terminating nul or invalid match. - move strnstr to LogUtils.h, drop size checking of needle and clearly report the list of needles used with android::strnstr - replace 'sizeof(static const char[]) - 1' with strlen. Test: gTest liblog-unit-test, logd-unit-tests & logcat-unit-tests Bug: 30792935 Bug: 36536248 Bug: 35468874 Bug: 34949125 Bug: 34606909 Bug: 36075298 Bug: 36608728 Change-Id: I161bf03ba029050e809b31cceef03f729d318866 --- libutils/include/utils/FastStrcmp.h | 47 +++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 12 deletions(-) (limited to 'libutils/include') diff --git a/libutils/include/utils/FastStrcmp.h b/libutils/include/utils/FastStrcmp.h index 3844e7d96..5cadc943a 100644 --- a/libutils/include/utils/FastStrcmp.h +++ b/libutils/include/utils/FastStrcmp.h @@ -17,6 +17,13 @@ #ifndef _ANDROID_UTILS_FASTSTRCMP_H__ #define _ANDROID_UTILS_FASTSTRCMP_H__ +#include +#include + +#ifndef __predict_true +#define __predict_true(exp) __builtin_expect((exp) != 0, 1) +#endif + #ifdef __cplusplus // Optimized for instruction cache locality @@ -28,25 +35,41 @@ // // fastcmp(str1, str2, len) // -// NB: Does not work for the case insensitive str*cmp functions. +// NB: use fasticmp for the case insensitive str*cmp functions. // NB: Returns boolean, do not use if expecting to check negative value. // Thus not semantically identical to the expected function behavior. -template -static inline int fastcmp(const char *l, const char *r, const size_t s) { - return (*l != *r) || cmp(l + 1, r + 1, s - 1); +template +static inline int fastcmp(const char* l, const char* r, const size_t s) { + const ssize_t n = s; // To help reject negative sizes, treat like zero + return __predict_true(n > 0) && + ((*l != *r) || (__predict_true(n > 1) && cmp(l + 1, r + 1, n - 1))); +} + +template +static inline int fasticmp(const char* l, const char* r, const size_t s) { + const ssize_t n = s; // To help reject negative sizes, treat like zero + return __predict_true(n > 0) && + ((tolower(*l) != tolower(*r)) || (__predict_true(n > 1) && cmp(l + 1, r + 1, n - 1))); +} + +template +static inline int fastcmp(const void* lv, const void* rv, const size_t s) { + const char* l = static_cast(lv); + const char* r = static_cast(rv); + const ssize_t n = s; // To help reject negative sizes, treat like zero + return __predict_true(n > 0) && + ((*l != *r) || (__predict_true(n > 1) && cmp(l + 1, r + 1, n - 1))); } -template -static inline int fastcmp(const void *lv, const void *rv, const size_t s) { - const char *l = static_cast(lv); - const char *r = static_cast(rv); - return (*l != *r) || cmp(l + 1, r + 1, s - 1); +template +static inline int fastcmp(const char* l, const char* r) { + return (*l != *r) || (__predict_true(*l) && cmp(l + 1, r + 1)); } -template -static inline int fastcmp(const char *l, const char *r) { - return (*l != *r) || cmp(l + 1, r + 1); +template +static inline int fasticmp(const char* l, const char* r) { + return (tolower(*l) != tolower(*r)) || (__predict_true(*l) && cmp(l + 1, r + 1)); } #endif -- cgit v1.2.3