diff --git a/CMakeLists.txt b/CMakeLists.txt index 4762954..645e8e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,49 @@ option(COSE_C_INCLUDE_MAC0 "Include COSE_MAC0" ON) option(COSE_C_INCLUDE_SIGN "Include COSE_SIGN" ON) option(COSE_C_INCLUDE_SIGN1 "Include COSE_SIGN1" ON) option(COSE_C_INCLUDE_COUNTERSIGN "Include COSE_COUNTERSIGN" OFF) +option(COSE_C_VALGRIND_MEMORY_CHECK "use Valgrind to check memory, \ + run `ctest -D ExperimentalMemCheck` then after build to run tests with valgrind" OFF) + +if(COSE_C_VALGRIND_MEMORY_CHECK) + find_program(MEMORYCHECK_COMMAND valgrind) + if(NOT MEMORYCHECK_COMMAND) + message(FATAL_ERROR "valgrind not found.") + endif() + set(MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full") + set(MEMORYCHECK_SUPPRESSIONS_FILE "${PROJECT_SOURCE_DIR}/valgrind_suppress.txt") +endif() + +set(COSE_C_USE_SANITIZER + "none" + CACHE + STRING + " \ + Name of the sanitizer which the user whats to use \ + This behaviour is the same is turning on one the sanitizer flags below \ + This option is a convenience option \ + ") +set_property(CACHE COSE_C_USE_SANITIZER PROPERTY STRINGS none address memory leak undefined) + +set(COSE_C_USE_ADDRESS_SANITIZER OFF) +set(COSE_C_USE_MEMORY_SANITIZER OFF) +set(COSE_C_USE_LEAK_SANITIZER OFF) +set(COSE_C_USE_UNDEFINED_SANITIZER OFF) + +if(COSE_C_USE_SANITIZER STREQUAL "address") + set(COSE_C_USE_ADDRESS_SANITIZER ON) +endif() + +if(COSE_C_USE_SANITIZER STREQUAL "memory") + set(COSE_C_USE_MEMORY_SANITIZER ON) +endif() + +if(COSE_C_USE_SANITIZER STREQUAL "leak") + set(COSE_C_USE_LEAK_SANITIZER ON) +endif() + +if(COSE_C_USE_SANITIZER STREQUAL "undefined") + set(COSE_C_USE_UNDEFINED_SANITIZER ON) +endif() # Set the output of the libraries and executables. set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) @@ -127,7 +170,7 @@ if(COSE_C_BUILD_DOCS) endif() ############################################################################### -# DEPENDENCIES +# STATIC ANALYSIS ############################################################################### if(COSE_C_RUN_CLANG_TIDY) @@ -140,6 +183,8 @@ if(COSE_C_RUN_CLANG_TIDY) endif() endif(COSE_C_RUN_CLANG_TIDY) +include(sanitizers) + ############################################################################### # DEPENDENCIES ############################################################################### @@ -271,6 +316,12 @@ message(STATUS "CMAKE_VERSION:...................${CMAKE_VERSION}") message(STATUS "CMAKE_C_COMPILER:................${CMAKE_C_COMPILER}") message(STATUS "CMAKE_CXX_COMPILER:..............${CMAKE_CXX_COMPILER}") message(STATUS "CLANG_TIDY_EXE:..................${CLANG_TIDY_EXE}") +message(STATUS "COSE_C_USE_SANITIZER:............${COSE_C_USE_SANITIZER}") +message(STATUS "COSE_C_USE_ADDRESS_SANITIZER:....${COSE_C_USE_ADDRESS_SANITIZER}") +message(STATUS "COSE_C_USE_MEMORY_SANITIZER:.....${COSE_C_USE_MEMORY_SANITIZER}") +message(STATUS "COSE_C_USE_LEAK_SANITIZER:.......${COSE_C_USE_LEAK_SANITIZER}") +message(STATUS "COSE_C_USE_UNDEFINED_SANITIZER:..${COSE_C_USE_UNDEFINED_SANITIZER}") +message(STATUS "COSE_C_VALGRIND_MEMORY_CHECK:....${COSE_C_VALGRIND_MEMORY_CHECK}") message(STATUS "project_cn_cbor_SOURCE_DIR:......${project_cn_cbor_SOURCE_DIR}") message(STATUS "project_cn_cbor_BINARY_DIR:......${project_cn_cbor_BINARY_DIR}") message(STATUS "project_mbedtls_SOURCE_DIR:......${project_mbedtls_SOURCE_DIR}") diff --git a/cmake/sanitizers.cmake b/cmake/sanitizers.cmake new file mode 100644 index 0000000..89269fc --- /dev/null +++ b/cmake/sanitizers.cmake @@ -0,0 +1,38 @@ +if(COSE_C_USE_ADDRESS_SANITIZER) + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address -g") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address -g") + set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address ") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=address") +endif(COSE_C_USE_ADDRESS_SANITIZER) + +if(COSE_C_USE_LEAK_SANITIZER) + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=leak -g") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=leak -g") + set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=leak") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=leak ") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=leak ") +endif(COSE_C_USE_LEAK_SANITIZER) + +if(COSE_C_USE_MEMORY_SANITIZER) + # NOTE: memory sanitizer can only run on x86_64 linux https://github.com/google/sanitizers/wiki/MemorySanitizer + # and only works with clang, no gcc support + + if(NOT CMAKE_C_COMPILER_ID MATCHES "Clang") + message(FATAL_ERROR "COSE_C_USE_MEMORY_SANITIZER is ON, but this option is only supported with clang compiler") + endif() + + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=memory -g") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=memory -g") + set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=memory ") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=memory") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=memory") +endif(COSE_C_USE_MEMORY_SANITIZER) + +if(COSE_C_USE_UNDEFINED_SANITIZER) + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=undefined -g") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=undefined -g") + set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=undefined") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=undefined ") +endif(COSE_C_USE_UNDEFINED_SANITIZER) diff --git a/dumper/dumper.c b/dumper/dumper.c index fea6500..aa17ad8 100644 --- a/dumper/dumper.c +++ b/dumper/dumper.c @@ -235,9 +235,7 @@ void WrapPrintF(FILE* fp, char* format, ...) void Indent(FILE* fp, int depth) { - int i; - - for (i = 0; i < depth; i++) { + for (int i = 0; i < depth; i++) { WrapPrintF(fp, " "); } } @@ -250,10 +248,9 @@ void PrintUsage() void DumpBytes(FILE* fp, const cn_cbor* cbor) { - int i; - int fText = true; + bool fText = true; - for (i = 0; i < cbor->length; i++) { + for (int i = 0; i < cbor->length; i++) { if ((cbor->v.bytes[i] < 32) || (cbor->v.bytes[i] > 126) || (cbor->v.bytes[i] == '\'')) { fText = false; @@ -262,13 +259,13 @@ void DumpBytes(FILE* fp, const cn_cbor* cbor) if (fText && (cbor->length > 0)) { WrapPrintF(fp, "'"); - for (i = 0; i < cbor->length; i++) { + for (int i = 0; i < cbor->length; i++) { WrapPrintF(fp, "%c", cbor->v.bytes[i]); } WrapPrintF(fp, "'"); } else { WrapPrintF(fp, "h'"); - for (i = 0; i < cbor->length; i++) { + for (int i = 0; i < cbor->length; i++) { WrapPrintF(fp, "%02x", cbor->v.bytes[i]); } WrapPrintF(fp, "'"); @@ -511,7 +508,6 @@ void DumpTree(const cn_cbor* cbor, int main(int argc, char** argv) { - int i; FILE* in = NULL; FILE* out = NULL; byte* pb = NULL; @@ -521,7 +517,7 @@ int main(int argc, char** argv) int forXML = false; FOO* root = NULL; - for (i = 1; i < argc; i++) { + for (int i = 1; i < argc; i++) { if ((argv[i][0] == '-') || (argv[i][0] == '/')) { if (strcmp(&argv[i][1], "someoption") == 0) { } else if (strcmp(&argv[i][1], "xml=yes") == 0) { diff --git a/src/openssl.c b/src/openssl.c index a050b6a..a377f9c 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -1012,9 +1012,8 @@ bool HMAC_Validate(COSE_MacMessage *pcose, HMAC_CTX *ctx = NULL; const EVP_MD *pmd = NULL; byte *rgbOut = NULL; - unsigned int cbOut; + unsigned int cbOut = 0 ; bool f = false; - unsigned int i; #ifdef USE_CBOR_CONTEXT cn_cbor_context *context = &pcose->m_message.m_allocContext; #endif @@ -1052,7 +1051,7 @@ bool HMAC_Validate(COSE_MacMessage *pcose, if (cn->length > (int)cbOut) { return false; } - for (i = 0; i < (unsigned int)TSize / 8; i++) { + for (unsigned int i = 0; i < (unsigned int)TSize / 8; i++) { f |= (cn->v.bytes[i] != rgbOut[i]); } diff --git a/test/json.c b/test/json.c index 0eb426d..80dda58 100644 --- a/test/json.c +++ b/test/json.c @@ -21,12 +21,11 @@ const cn_cbor *ParseString(char *rgch, int ib, int cch) { char ch; int ib2; - cn_cbor *node = NULL; cn_cbor *parent = NULL; cn_cbor *root = NULL; for (; ib < cch; ib++) { - node = NULL; + cn_cbor *node = NULL; ch = rgch[ib]; switch (ch) { case '{': diff --git a/test/test.c b/test/test.c index ce712fa..bedc63e 100644 --- a/test/test.c +++ b/test/test.c @@ -872,7 +872,7 @@ void RunCorners() #endif } -void RunMemoryTest(const char* szFileName) +static void RunMemoryTest(const char* szFileName) { #ifdef USE_CBOR_CONTEXT unsigned int iFail; @@ -1218,11 +1218,9 @@ bool ProcessFile(const cn_cbor* pControl, return true; } -void RunFileTest(const char* szFileName) +static void RunFileTest(const char* szFileName) { - const cn_cbor* pControl = NULL; - - pControl = ParseJson(szFileName); + const cn_cbor* pControl = ParseJson(szFileName); // // If we are given a file name, then process the file name