From 40c2de92974c65d56fd7408d47a9cd8b235b36d4 Mon Sep 17 00:00:00 2001 From: Mateusz Cegielka Date: Thu, 30 Jul 2020 14:01:32 +0200 Subject: [PATCH] Add warning on CKM TrustZone space leak Current implementation of ckmc_remove_user_data is not able to remove individual objects from TrustZone, because their names are stored in a possibly encrypted database. This rarely happens in actual code, but tests extensively use this function to clean up objects they create. Because of this, running CKM tests multiple times with TrustZone enabled may exceed TrustZone limits. Fixing the behaviour is a larger task, and making all tests clean up individual objects is too verbose, complex and error-prone for a bug workaround that only affects developers (this approach has already been tried once, and it was removed years ago). I have added a heuristic check that tries to create a single-byte data object in TrustZone. If that fails, it displays a warning message explaining the problem and suggesting to reset TrustZone and key-manager state, as well as instructions on how to do use using Tizen emulator and tef-simulator. Change-Id: Id99c22c33f3e5adfbeff5c7b1b58d2d995ed4cca --- src/CMakeLists.txt | 5 ++++ src/ckm-integration/main.cpp | 9 ++++-- src/ckm/CMakeLists.txt | 11 +------ src/ckm/privileged/main.cpp | 7 ++++- src/ckm/unprivileged/main.cpp | 7 ++++- src/common/CMakeLists.txt | 2 ++ src/common/ckm_helpers.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++ src/common/ckm_helpers.h | 25 ++++++++++++++++ 8 files changed, 120 insertions(+), 14 deletions(-) create mode 100644 src/common/ckm_helpers.cpp create mode 100644 src/common/ckm_helpers.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 736b6e8..954a51a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,6 +32,11 @@ ENDIF(DPL_WITH_DLOG) ADD_DEFINITIONS(${SYS_FRAMEWORK_TEST_OTHER_CFLAGS}) +OPTION("TZ_BACKEND" OFF) +IF(TZ_BACKEND) + ADD_DEFINITIONS("-DTZ_BACKEND") +ENDIF(TZ_BACKEND) + include(framework/config.cmake) SET(DPL_FRAMEWORK_TEST_LIBRARY "dpl-test-framework") diff --git a/src/ckm-integration/main.cpp b/src/ckm-integration/main.cpp index 6c5ea6b..f84d413 100644 --- a/src/ckm-integration/main.cpp +++ b/src/ckm-integration/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2020 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,14 @@ * @version 1.0 */ #include +#include int main (int argc, char *argv[]) { - return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); + int exitCode = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); + + detectCkmBugTrustzoneLeak(); + + return exitCode; } diff --git a/src/ckm/CMakeLists.txt b/src/ckm/CMakeLists.txt index 97f1239..a07a007 100644 --- a/src/ckm/CMakeLists.txt +++ b/src/ckm/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2013-2019 Samsung Electronics Co., Ltd All Rights Reserved +# Copyright (c) 2013-2020 Samsung Electronics Co., Ltd All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -29,15 +29,6 @@ ENDIF (DEFINED SECURITY_MDFPP_STATE_ENABLED) ADD_DEFINITIONS("-DCKM_TEST_DIR=\"${CKM_TEST_DIR}\"") ADD_DEFINITIONS("-DCKM_RW_DATA_DIR=\"${CKM_RW_DATA_DIR}\"") -OPTION("TZ_BACKEND" OFF) -IF(TZ_BACKEND) - ADD_DEFINITIONS("-DTZ_BACKEND") -ENDIF(TZ_BACKEND) - -OPTION("TZ_BACKEND" OFF) -IF(TZ_BACKEND) - ADD_DEFINITIONS("-DTZ_BACKEND") -ENDIF(TZ_BACKEND) PKG_CHECK_MODULES(CKM_TEST_COMMON_DEP REQUIRED diff --git a/src/ckm/privileged/main.cpp b/src/ckm/privileged/main.cpp index fd5cd13..8e25fbe 100644 --- a/src/ckm/privileged/main.cpp +++ b/src/ckm/privileged/main.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -371,5 +372,9 @@ int main(int argc, char *argv[]) std::cerr << argv[0] << " should be executed as root. Aborting" << std::endl; return -1; } - return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); + int exitCode = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); + + detectCkmBugTrustzoneLeak(); + + return exitCode; } diff --git a/src/ckm/unprivileged/main.cpp b/src/ckm/unprivileged/main.cpp index f4a2eec..15e0a80 100644 --- a/src/ckm/unprivileged/main.cpp +++ b/src/ckm/unprivileged/main.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -2942,5 +2943,9 @@ int main(int argc, char *argv[]) return -1; } - return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); + int exitCode = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); + + detectCkmBugTrustzoneLeak(); + + return exitCode; } diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 367d1e0..1519ecf 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -15,6 +15,7 @@ PKG_CHECK_MODULES(COMMON_TARGET_DEP cynara-creds-sd-bus security-manager security-privilege-manager + key-manager REQUIRED ) @@ -48,6 +49,7 @@ SET(COMMON_TARGET_TEST_SOURCES ${PROJECT_SOURCE_DIR}/src/common/tzplatform.cpp ${PROJECT_SOURCE_DIR}/src/common/privilege_manager.cpp ${PROJECT_SOURCE_DIR}/src/common/scoped_process_label.cpp + ${PROJECT_SOURCE_DIR}/src/common/ckm_helpers.cpp ) #system and local includes diff --git a/src/common/ckm_helpers.cpp b/src/common/ckm_helpers.cpp new file mode 100644 index 0000000..41bbfc3 --- /dev/null +++ b/src/common/ckm_helpers.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file ckm_helpers.cpp + * @author Mateusz Cegielka (m.cegielka@samsung.com) + * @version 1.0 + * @brief Utilities common to ckm and ckm-integration tests + */ + +#include + +#include + +#include + +void detectCkmBugTrustzoneLeak() +{ +#ifdef TZ_BACKEND + const char* alias = "detect-bug-trustzone-leak"; + unsigned char data[] = {0}; + + ckmc_raw_buffer_s buffer; + buffer.data = data; + buffer.size = sizeof(data) / sizeof(data[0]); + ckmc_policy_s policy; + policy.password = nullptr; + policy.extractable = true; + + int ret = ckmc_save_data(alias, buffer, policy); + ckmc_remove_alias(alias); + + if (ret == CKMC_ERROR_SERVER_ERROR) { + std::cerr << "\x1B[1;33m" + "### Warning #############################################################\n" + "# TrustZone may have ran out of memory due to running CKM tests #\n" + "# multiple times. This happens because ckmc_remove_user_data is not #\n" + "# able to remove individual objects stored in TrustZone, as the user #\n" + "# database may be encrypted. If that happens, tests that use TrustZone #\n" + "# backend will start failing, and you will need to somehow restore #\n" + "# TrustZone and key-manager to an earlier state, before the memory was #\n" + "# exhausted. #\n" + "# #\n" + "# If you're working with a Tizen emulator and tef-simulator, there are #\n" + "# two ways to do this. The simpler way to do so are QEMU snapshots. You #\n" + "# should have access to `make snapshot-restore` and #\n" + "# `make snapshot-push` commands in the same directory where you run #\n" + "# `run.sh`, and a snapshot with a clean image is available by default. #\n" + "# The second, faster way to do this is to run `rm -r #\n" + "# /opt/usr/apps/ta_sdk/data/* /opt/data/ckm/{db*,key*,removed*} && #\n" + "# systemctl restart central-key-manager tef-simulator. #\n" + "#########################################################################\n" + "\x1B[0m\n"; + } +#endif +} diff --git a/src/common/ckm_helpers.h b/src/common/ckm_helpers.h new file mode 100644 index 0000000..47a761c --- /dev/null +++ b/src/common/ckm_helpers.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file ckm_helpers.h + * @author Mateusz Cegielka (m.cegielka@samsung.com) + * @version 1.0 + * @brief Utilities common to ckm and ckm-integration tests + */ + +#pragma once + +void detectCkmBugTrustzoneLeak(); -- 2.7.4