Add warning on CKM TrustZone space leak 25/239925/4
authorMateusz Cegielka <m.cegielka@samsung.com>
Thu, 30 Jul 2020 12:01:32 +0000 (14:01 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 2 Oct 2020 10:51:02 +0000 (10:51 +0000)
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
src/ckm-integration/main.cpp
src/ckm/CMakeLists.txt
src/ckm/privileged/main.cpp
src/ckm/unprivileged/main.cpp
src/common/CMakeLists.txt
src/common/ckm_helpers.cpp [new file with mode: 0644]
src/common/ckm_helpers.h [new file with mode: 0644]

index 736b6e8..954a51a 100644 (file)
@@ -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")
index 6c5ea6b..f84d413 100644 (file)
@@ -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.
  * @version    1.0
  */
 #include <dpl/test/test_runner.h>
+#include <ckm_helpers.h>
 
 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;
 }
 
 
index 97f1239..a07a007 100644 (file)
@@ -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
index fd5cd13..8e25fbe 100644 (file)
@@ -29,6 +29,7 @@
 #include <scoped-app-context.h>
 #include <ckm-common.h>
 #include <ckm-privileged-common.h>
+#include <ckm_helpers.h>
 
 #include <ckm/ckm-manager.h>
 #include <ckm/ckm-control.h>
@@ -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;
 }
index f4a2eec..15e0a80 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <tests_common.h>
 #include <test-certs.h>
+#include <ckm_helpers.h>
 
 #include <ckm-common.h>
 #include <ckm/ckm-manager.h>
@@ -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;
 }
index 367d1e0..1519ecf 100644 (file)
@@ -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 (file)
index 0000000..41bbfc3
--- /dev/null
@@ -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 <ckm_helpers.h>
+
+#include <iostream>
+
+#include <ckmc/ckmc-manager.h>
+
+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 (file)
index 0000000..47a761c
--- /dev/null
@@ -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();