From 5cf1345192bcf1eeb23016d2ba3356794e595ced Mon Sep 17 00:00:00 2001 From: XavierChanth Date: Mon, 23 Dec 2024 14:53:22 -0500 Subject: [PATCH 1/3] feat: memcheck with tests --- CMakeLists.txt | 9 ++++ justfile | 47 +++++++++++++++------ packages/atauth/src/atactivate_arg_parser.c | 11 ++--- packages/atchops/src/rsa_key.c | 5 ++- packages/atchops/tests/test_rsaencrypt.c | 16 ++++--- packages/atchops/tests/test_rsasign.c | 2 +- packages/atclient/tests/CMakeLists.txt | 1 - packages/atcommons/tests/CMakeLists.txt | 16 +++---- valgrind.Dockerfile | 16 +++++++ 9 files changed, 86 insertions(+), 37 deletions(-) create mode 100644 valgrind.Dockerfile diff --git a/CMakeLists.txt b/CMakeLists.txt index 08f7819a..e52444c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ # Configurable options set(TARGET_ESPIDF FALSE CACHE BOOL "Build for the espidf platform") +option(ATSDK_MEMCHECK "Enable memcheck configuration" OFF) option(ATSDK_BUILD_TESTS "Build tests for atsdk ON | \"unit\" | \"func\" " OFF) # to avoid caching issues @@ -22,6 +23,9 @@ else() set(ATSDK_BUILD_FUNCTIONAL_TESTS OFF) endif() +# Disable building mbedtls programs +set(ENABLE_PROGRAMS OFF) + # Basic project setup cmake_minimum_required(VERSION 3.24) set(CMAKE_C_STANDARD 99) @@ -111,5 +115,10 @@ if(ATSDK_BUILD_FUNCTIONAL_TESTS) endif() if(ATSDK_BUILD_UNIT_TESTS OR ATSDK_BUILD_FUNCTIONAL_TESTS) + if(ATSDK_MEMCHECK) + include(CTest) + add_compile_options(-fsanitize=address) + add_link_options(-fsanitize=address) + endif() enable_testing() endif() diff --git a/justfile b/justfile index 5cd4c8c9..398eb6ea 100644 --- a/justfile +++ b/justfile @@ -2,6 +2,7 @@ alias build := build-debug alias test := test-all alias unit := test-unit alias func := test-func +alias memd := memcheck-docker set dotenv-filename := "just.env" set dotenv-load @@ -10,6 +11,9 @@ setup: configure-debug configure-test-func ln -s $PWD/build/debug/compile_commands.json $PWD ln -s $PWD/build/test-func/compile_commands.json $PWD/tests +setup-memcheck-docker: + docker build --platform linux/amd64 -t atc-memcheck-docker:latest -f $PWD/valgrind.Dockerfile $PWD + clean: rm -rf $PWD/build rm $PWD/compile_commands.json @@ -33,6 +37,9 @@ build-test-func: configure-test-func build-test-all: configure-test-all cmake --build $PWD/build/test-all +build-test-memcheck: configure-test-memcheck + cmake --build $PWD/build/test-memcheck + test-unit: build-test-unit ctest --test-dir $PWD/build/test-unit @@ -42,6 +49,12 @@ test-func: build-test-func test-all: build-test-all ctest --test-dir $PWD/build/test-all +memcheck: build-test-memcheck + ctest -T memcheck --test-dir $PWD/build/test-memcheck + +memcheck-docker: + docker run --rm --platform linux/amd64 --mount type=bind,src=$PWD,dst=/mnt/at_c atc-memcheck-docker:latest + configure-debug: cmake -B $PWD/build/debug -S $PWD \ -DCMAKE_INSTALL_PREFIX="$HOME/.local/" \ @@ -50,8 +63,7 @@ configure-debug: -DCMAKE_C_COMPILER=$C_COMPILER \ -DCMAKE_C_FLAGS="-std=c99 -Wno-error" \ -DATSDK_BUILD_TESTS=OFF \ - -DATSDK_BUILD_UNIT_TESTS=OFF \ - -DATSDK_BUILD_FUNCTIONAL_TESTS=OFF + -DATSDK_MEMCHECK=OFF configure-release: cmake -B $PWD/build/release -S $PWD \ @@ -59,26 +71,23 @@ configure-release: -DCMAKE_C_COMPILER=$C_COMPILER \ -DCMAKE_C_FLAGS="-std=c99 -Wno-error" \ -DATSDK_BUILD_TESTS=OFF \ - -DATSDK_BUILD_UNIT_TESTS=OFF \ - -DATSDK_BUILD_FUNCTIONAL_TESTS=OFF + -DATSDK_MEMCHECK=OFF configure-test-unit: cmake -B $PWD/build/test-unit -S $PWD \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_C_COMPILER=$C_COMPILER \ - -DCMAKE_C_FLAGS="-std=c99 -Wno-error" \ - -DATSDK_BUILD_TESTS=OFF \ - -DATSDK_BUILD_UNIT_TESTS=ON \ - -DATSDK_BUILD_FUNCTIONAL_TESTS=OFF + -DCMAKE_C_FLAGS="-std=c99 -Wno-error " \ + -DATSDK_BUILD_TESTS="unit" \ + -DATSDK_MEMCHECK=OFF configure-test-func: cmake -B $PWD/build/test-func -S $PWD \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_C_COMPILER=$C_COMPILER \ - -DCMAKE_C_FLAGS="-std=c99 -Wno-error" \ - -DATSDK_BUILD_TESTS=OFF \ - -DATSDK_BUILD_UNIT_TESTS=OFF \ - -DATSDK_BUILD_FUNCTIONAL_TESTS=ON \ + -DCMAKE_C_FLAGS="-std=c99 -Wno-error " \ + -DATSDK_BUILD_TESTS="func" \ + -DATSDK_MEMCHECK=OFF \ -DFIRST_ATSIGN="\"$FIRST_ATSIGN\"" \ -DSECOND_ATSIGN="\"$SECOND_ATSIGN\"" @@ -86,8 +95,20 @@ configure-test-all: cmake -B $PWD/build/test-all -S $PWD \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_C_COMPILER=$C_COMPILER \ - -DCMAKE_C_FLAGS="-std=c99 -Wno-error" \ + -DCMAKE_C_FLAGS="-std=c99 -Wno-error " \ + -DATSDK_BUILD_TESTS=ON \ + -DATSDK_MEMCHECK=OFF \ + -DFIRST_ATSIGN="\"$FIRST_ATSIGN\"" \ + -DSECOND_ATSIGN="\"$SECOND_ATSIGN\"" + +configure-test-memcheck: + cmake -B $PWD/build/test-memcheck -S $PWD \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_C_COMPILER=$C_COMPILER \ + -DCMAKE_C_FLAGS="-std=gnu99 -Wno-error" \ -DATSDK_BUILD_TESTS=ON \ + -DBUILD_SHARED_LIBS=ON \ + -DATSDK_MEMCHECK=ON \ -DFIRST_ATSIGN="\"$FIRST_ATSIGN\"" \ -DSECOND_ATSIGN="\"$SECOND_ATSIGN\"" diff --git a/packages/atauth/src/atactivate_arg_parser.c b/packages/atauth/src/atactivate_arg_parser.c index f4e64106..605edfb9 100644 --- a/packages/atauth/src/atactivate_arg_parser.c +++ b/packages/atauth/src/atactivate_arg_parser.c @@ -12,9 +12,10 @@ int atactivate_parse_args(const int argc, char *argv[], char **atsign, char **cr char **app_name, char **device_name, char **namespaces, char **root_host, int *root_port) { int ret = 0, opt = 0; char *root_fqdn = NULL; - const char *usage = "Usage: \n\tActivate: \t./atactivate -a atsign -c cram-secret [-k path_to_store_keysfile] [-r root-domain]" - "\n\n\tNew enrollment: ./at_auth_cli -a atsign -s otp/spp -p app_name -d device_name -n " - "namespaces(\"wavi:rw,buzz:r\") [-k path_to_store_keysfile] [-r root-domain]\n"; + const char *usage = + "Usage: \n\tActivate: \t./atactivate -a atsign -c cram-secret [-k path_to_store_keysfile] [-r root-domain]" + "\n\n\tNew enrollment: ./at_auth_cli -a atsign -s otp/spp -p app_name -d device_name -n " + "namespaces(\"wavi:rw,buzz:r\") [-k path_to_store_keysfile] [-r root-domain]\n"; // Parse command-line arguments while ((opt = getopt(argc, argv, "a:c:k:s:p:d:n:r:vh")) != -1) { @@ -140,12 +141,12 @@ int atactivate_parse_args(const int argc, char *argv[], char **atsign, char **cr } int parse_root_domain(const char *root_domain_string, char **root_host, int *root_port) { - if(root_domain_string == NULL) { + if (root_domain_string == NULL) { return 1; } *root_host = strdup(strtok((char *)root_domain_string, ":")); *root_port = atoi(strtok(NULL, ":")); - if(*root_host == NULL || root_port == NULL) { + if (*root_host == NULL || root_port == NULL) { return 1; } return 0; diff --git a/packages/atchops/src/rsa_key.c b/packages/atchops/src/rsa_key.c index 89ff9116..e9020480 100644 --- a/packages/atchops/src/rsa_key.c +++ b/packages/atchops/src/rsa_key.c @@ -320,12 +320,13 @@ int atchops_rsa_key_generate_base64(unsigned char **public_key_base64_output, // 7b. Second, we need to add headers to the PKCS#1 formatted private key to make it PKCS#8 formatted const size_t private_key_pkcs8_size = private_key_non_base64_len + 22; - private_key_pkcs8 = (unsigned char *)malloc(private_key_pkcs8_size); + const size_t private_key_alloc_size = private_key_pkcs8_size + 4; + private_key_pkcs8 = (unsigned char *)malloc(private_key_alloc_size); if (private_key_pkcs8 == NULL) { atlogger_log(TAG, ATLOGGER_LOGGING_LEVEL_ERROR, "Failed to allocate memory for private_key_pkcs8\n"); goto exit; } - memset(private_key_pkcs8, 0, sizeof(unsigned char) * private_key_pkcs8_size); + memset(private_key_pkcs8, 0, sizeof(unsigned char) * private_key_alloc_size); // https://lapo.it/asn1js/ use this to debug // PrivateKeyInfo SEQUENCE (3 elements) private_key_pkcs8[0] = 0x30; // constructed sequence tag diff --git a/packages/atchops/tests/test_rsaencrypt.c b/packages/atchops/tests/test_rsaencrypt.c index 7d6e6476..5b12daef 100644 --- a/packages/atchops/tests/test_rsaencrypt.c +++ b/packages/atchops/tests/test_rsaencrypt.c @@ -1,9 +1,9 @@ #include "atchops/rsa.h" +#include #include #include #include -#include // #define PUBLICKEYBASE64 \ // "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg3P7mefqZg2GNQPiEHYinmTYUcbbW2Ar9Wi5LCD/" \ @@ -12,7 +12,12 @@ // "FutJTF8M6LKQY8E+h2cQjTEn3RRJlcMp4rwq/0GNmm3mNY5EhUcamKiSWILG9a8nYzeIUafXmESCZk+J1yVu9QcmXP8Dokv+4KLv76/" \ // "Y1RsqQIDAQAB" -#define PUBLICKEYBASE64 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0puvhTIiwSaqM9j6zPbvgEaj0Byg4AU/mtL5d6j6hnjJt6BDeztfqOxmLz9s+5NYHnS5ZExbtOohlFZXqISI39EWBsKgcqTOgfjCCWj3Cf1BbbNFiz/D322BvT6TLYeMtErSaQYPlQk4i3GZkp2SfwQcJ9CM7Gp+uCHTZ3NxEuU3Ut3roYOhKEVI72XesMPDlf4y8nSAsrpWs9KbU3isflj0yQXqMH3NXbDn2ie7h02Ul+u1fBuRs05TEFfaYt7R5ia+4USvcnkzGtA7mm8Xyo7AF2ZWnWYfx+368936buo7Vu9twt4Xynd/rvMxv2Fc/H/CFN9SI/n6zRN97uf85wIDAQAB" +#define PUBLICKEYBASE64 \ + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0puvhTIiwSaqM9j6zPbvgEaj0Byg4AU/" \ + "mtL5d6j6hnjJt6BDeztfqOxmLz9s+5NYHnS5ZExbtOohlFZXqISI39EWBsKgcqTOgfjCCWj3Cf1BbbNFiz/" \ + "D322BvT6TLYeMtErSaQYPlQk4i3GZkp2SfwQcJ9CM7Gp+" \ + "uCHTZ3NxEuU3Ut3roYOhKEVI72XesMPDlf4y8nSAsrpWs9KbU3isflj0yQXqMH3NXbDn2ie7h02Ul+u1fBuRs05TEFfaYt7R5ia+" \ + "4USvcnkzGtA7mm8Xyo7AF2ZWnWYfx+368936buo7Vu9twt4Xynd/rvMxv2Fc/H/CFN9SI/n6zRN97uf85wIDAQAB" #define PLAINTEXT "banana" @@ -28,7 +33,6 @@ int main() { const size_t ciphertextsize = 256; unsigned char ciphertext[ciphertextsize]; memset(ciphertext, 0, sizeof(unsigned char) * ciphertextsize); - size_t ciphertextlen = 0; atchops_rsa_key_public_key publickey; atchops_rsa_key_public_key_init(&publickey); @@ -46,11 +50,9 @@ int main() { goto ret; } printf("atchops_rsa_encrypt (success): %d\n", ret); - printf("ciphertext (base64 encoded): \"%s\"\n", ciphertext); + printf("ciphertext (base64 encoded): \"%.*s\"\n", (int)ciphertextsize, ciphertext); goto ret; -ret: { - return ret; -} +ret: { return ret; } } diff --git a/packages/atchops/tests/test_rsasign.c b/packages/atchops/tests/test_rsasign.c index 5558733a..7e72c4b2 100644 --- a/packages/atchops/tests/test_rsasign.c +++ b/packages/atchops/tests/test_rsasign.c @@ -70,7 +70,7 @@ int main() { goto exit; } printf("atchops_rsa_sign (success): %d\n", ret); - printf("signature: \"%s\"\n", signature); + printf("signature: \"%.*s\"\n", SIGNATURE_SIZE, signature); ret = atchops_base64_encode(signature, SIGNATURE_SIZE, (unsigned char *)signaturebase64, SIGNATURE_BASE64_SIZE, &signaturebase64len); diff --git a/packages/atclient/tests/CMakeLists.txt b/packages/atclient/tests/CMakeLists.txt index d335d259..040e165c 100644 --- a/packages/atclient/tests/CMakeLists.txt +++ b/packages/atclient/tests/CMakeLists.txt @@ -8,4 +8,3 @@ foreach(file ${files}) target_link_libraries(${filename} PRIVATE atclient) add_test(NAME ${filename} COMMAND $) endforeach() - diff --git a/packages/atcommons/tests/CMakeLists.txt b/packages/atcommons/tests/CMakeLists.txt index ffd13783..7509d94b 100644 --- a/packages/atcommons/tests/CMakeLists.txt +++ b/packages/atcommons/tests/CMakeLists.txt @@ -1,11 +1,11 @@ include_directories(${PROJECT_SOURCE_DIR}/src) file(GLOB_RECURSE files ${CMAKE_CURRENT_LIST_DIR}/test_*.c) -foreach (file ${files}) - # ${filename} - without `.c` - get_filename_component(filename ${file} NAME) - string(REPLACE ".c" "" filename ${filename}) +foreach(file ${files}) + # ${filename} - without `.c` + get_filename_component(filename ${file} NAME) + string(REPLACE ".c" "" filename ${filename}) - add_executable(${filename} ${file}) - target_link_libraries(${filename} PRIVATE atcommons) - add_test(NAME ${filename} COMMAND $) -endforeach () \ No newline at end of file + add_executable(${filename} ${file}) + target_link_libraries(${filename} PRIVATE atcommons) + add_test(NAME ${filename} COMMAND $) +endforeach() diff --git a/valgrind.Dockerfile b/valgrind.Dockerfile new file mode 100644 index 00000000..19c07109 --- /dev/null +++ b/valgrind.Dockerfile @@ -0,0 +1,16 @@ +FROM ubuntu:24.04 + +RUN apt-get update; apt-get upgrade -y +RUN apt-get install -y git-core \ + build-essential \ + sudo \ + curl \ + just \ + valgrind \ + gcc \ + cmake + +WORKDIR /mnt/at_c + +CMD [ "just", "memcheck" ] + From f298141839cbc810a500412840331df73d1627fe Mon Sep 17 00:00:00 2001 From: XavierChanth Date: Fri, 3 Jan 2025 10:00:56 -0500 Subject: [PATCH 2/3] docs: comments in just file --- justfile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/justfile b/justfile index 398eb6ea..c84720e3 100644 --- a/justfile +++ b/justfile @@ -7,6 +7,8 @@ alias memd := memcheck-docker set dotenv-filename := "just.env" set dotenv-load +# SETUP COMMANDS + setup: configure-debug configure-test-func ln -s $PWD/build/debug/compile_commands.json $PWD ln -s $PWD/build/test-func/compile_commands.json $PWD/tests @@ -19,9 +21,13 @@ clean: rm $PWD/compile_commands.json rm $PWD/tests/compile_commands.json +# INSTALL COMMANDS + install: build-debug cmake: --build $PWD/build/debug --target install +# BUILD COMMANDS + build-debug: configure-debug cmake --build $PWD/build/debug @@ -40,6 +46,8 @@ build-test-all: configure-test-all build-test-memcheck: configure-test-memcheck cmake --build $PWD/build/test-memcheck +# TEST COMMANDS + test-unit: build-test-unit ctest --test-dir $PWD/build/test-unit @@ -55,6 +63,8 @@ memcheck: build-test-memcheck memcheck-docker: docker run --rm --platform linux/amd64 --mount type=bind,src=$PWD,dst=/mnt/at_c atc-memcheck-docker:latest +# CONFIGURE COMMANDS + configure-debug: cmake -B $PWD/build/debug -S $PWD \ -DCMAKE_INSTALL_PREFIX="$HOME/.local/" \ @@ -112,6 +122,8 @@ configure-test-memcheck: -DFIRST_ATSIGN="\"$FIRST_ATSIGN\"" \ -DSECOND_ATSIGN="\"$SECOND_ATSIGN\"" +# DIAGNOSTIC COMMANDS + show-env: echo "$FIRST_ATSIGN" echo "$SECOND_ATSIGN" From d7f35df2d601b1d43079a249cd7bf38e9f3721ba Mon Sep 17 00:00:00 2001 From: XavierChanth Date: Fri, 20 Dec 2024 15:39:32 -0500 Subject: [PATCH 3/3] chore: allow passing args to memcheck in just --- justfile | 9 +++++---- valgrind.Dockerfile | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/justfile b/justfile index c84720e3..86cc0197 100644 --- a/justfile +++ b/justfile @@ -57,11 +57,12 @@ test-func: build-test-func test-all: build-test-all ctest --test-dir $PWD/build/test-all -memcheck: build-test-memcheck - ctest -T memcheck --test-dir $PWD/build/test-memcheck +memcheck +ARGS='': build-test-memcheck + ctest -T memcheck --test-dir $PWD/build/test-memcheck {{ARGS}} -memcheck-docker: - docker run --rm --platform linux/amd64 --mount type=bind,src=$PWD,dst=/mnt/at_c atc-memcheck-docker:latest +memcheck-docker +ARGS='': + docker run --rm --platform linux/amd64 --mount type=bind,src=$PWD,dst=/mnt/at_c atc-memcheck-docker:latest \ + just memcheck {{ARGS}} # CONFIGURE COMMANDS diff --git a/valgrind.Dockerfile b/valgrind.Dockerfile index 19c07109..7916d56e 100644 --- a/valgrind.Dockerfile +++ b/valgrind.Dockerfile @@ -12,5 +12,5 @@ RUN apt-get install -y git-core \ WORKDIR /mnt/at_c -CMD [ "just", "memcheck" ] +CMD [ "tail", "-f", "/dev/null" ]