Add xtest 6015 (TA storage separation)

xtest 6015 is added to test storage isolation. It invokes a first TA to
create a persistent object. Then it uses a second TA to try and open an
object with the same name, which is expected to fail. Both TAs are
actually the same except for the UUID.

The test also attempts to simulate a file manipulation in the REE file
system (renaming the storage path of TA1 to match the TA2 directory).
This should fail as well.

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (QEMU)
Reviewed-by: David Brown <david.brown@linaro.org>
Tested-by: David Brown <david.brown@linaro.org> (Hikey android)
diff --git a/host/xtest/xtest_20000.c b/host/xtest/xtest_20000.c
index df0d913..ce2bc2a 100644
--- a/host/xtest/xtest_20000.c
+++ b/host/xtest/xtest_20000.c
@@ -55,12 +55,6 @@
 #define MIN(a,b) ((a)<(b) ? (a) : (b))
 #endif
 
-#define SWAP_BYTES_16(w16) ((((w16) & 0xFF00) >> 8) | (((w16) & 0xFF) << 8))
-#define SWAP_BYTES_32(w32) ((((w32) & 0xFF000000) >> 24) |\
-			    (((w32) & 0xFF0000) >> 8) |\
-			    (((w32) & 0xFF00) << 8) |\
-			    (((w32) & 0xFF) << 24))
-
 #define XTEST_ENC_FS(level, data_len, meta, block_num, version) \
 	{ \
 	  level, \
@@ -217,27 +211,6 @@
 	return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_CLOSE, &op, &org);
 }
 
-static int get_ta_dirname(TEEC_UUID *p_uuid, char *buffer, uint32_t len)
-{
-
-	if (p_uuid == NULL || buffer == NULL)
-		return 0;
-	
-	return snprintf(buffer, len,
-		        "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
-		        SWAP_BYTES_32(p_uuid->timeLow),
-		        SWAP_BYTES_16(p_uuid->timeMid),
-		        SWAP_BYTES_16(p_uuid->timeHiAndVersion),
-		        p_uuid->clockSeqAndNode[0],
-	                p_uuid->clockSeqAndNode[1],
-		        p_uuid->clockSeqAndNode[2],
-		        p_uuid->clockSeqAndNode[3],
-		        p_uuid->clockSeqAndNode[4],
-		        p_uuid->clockSeqAndNode[5],
-		        p_uuid->clockSeqAndNode[6],
-		        p_uuid->clockSeqAndNode[7]);
-}
-
 static int get_obj_filename(void *file_id, uint32_t file_id_length,
 			    char *buffer, uint32_t len)
 {
@@ -288,7 +261,7 @@
         char path[150];
         struct stat sb;
 
-        if (get_ta_dirname(p_uuid, ta_dirname, sizeof(ta_dirname)) &&
+        if (ree_fs_get_ta_dirname(p_uuid, ta_dirname, sizeof(ta_dirname)) &&
             get_obj_filename(file_id, file_id_length, obj_filename,
 			     sizeof(obj_filename))) {
                 if (file_type == META_FILE) {
@@ -325,7 +298,7 @@
 
 	memset(name, 0, sizeof(name));
 
-	if (get_ta_dirname(p_uuid, ta_dirname, sizeof(ta_dirname)) &&
+	if (ree_fs_get_ta_dirname(p_uuid, ta_dirname, sizeof(ta_dirname)) &&
 	    get_obj_filename(file_id, file_id_length, obj_filename,
 			     sizeof(obj_filename))) {
 
diff --git a/host/xtest/xtest_6000.c b/host/xtest/xtest_6000.c
index 956be70..4ba9e34 100644
--- a/host/xtest/xtest_6000.c
+++ b/host/xtest/xtest_6000.c
@@ -1352,6 +1352,113 @@
 
 DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6014)
 
+static int get_ta_storage_path(TEEC_UUID *p_uuid, char *buffer, uint32_t len)
+{
+	int s;
+
+	if (!p_uuid || !buffer)
+		return -1;
+
+	s = snprintf(buffer, len, "/data/tee/");
+	if (s < 0 || s >= (int)len)
+		return -1;
+
+	len -= s;
+	buffer += s;
+
+	s = ree_fs_get_ta_dirname(p_uuid, buffer, len);
+	return s;
+}
+
+static int rename_data_dir(TEEC_UUID *old, TEEC_UUID *nw)
+{
+	char opath[150];
+	char npath[150];
+	int s;
+
+	s = get_ta_storage_path(old, opath, sizeof(opath));
+	if (s < 0 || s >= (int)sizeof(opath)) {
+		s = -1;
+		goto exit;
+	}
+	s = get_ta_storage_path(nw, npath, sizeof(npath));
+	if (s < 0 || s >= (int)sizeof(opath)) {
+		s = -1;
+		goto exit;
+	}
+	s = rename(opath, npath);
+exit:
+	if (s < 0)
+		fprintf(stderr, "Warning: could not rename %s -> %s\n", opath,
+			npath);
+	return s;
+}
+
+static void xtest_tee_test_6015_single(ADBG_Case_t *c, uint32_t storage_id)
+{
+	TEEC_Session sess;
+	TEEC_Session sess2;
+	uint32_t orig;
+	uint32_t obj;
+	uint32_t obj2;
+	TEEC_UUID uuid = TA_STORAGE_UUID;
+	TEEC_UUID uuid2 = TA_STORAGE2_UUID;
+
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+		xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
+		return;
+
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+		xtest_teec_open_session(&sess2, &storage2_ta_uuid, NULL,
+					&orig)))
+		goto exit2;
+
+	/* TA #1 creates a persistent object  */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+		fs_create(&sess, file_01, sizeof(file_01),
+			  TEE_DATA_FLAG_ACCESS_WRITE |
+			  TEE_DATA_FLAG_ACCESS_READ |
+			  TEE_DATA_FLAG_ACCESS_WRITE_META, 0, data_00,
+			  sizeof(data_00), &obj, storage_id)))
+		goto exit;
+
+	/* TA #2 tries to open the object created by TA #1 */
+	if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_ITEM_NOT_FOUND,
+		fs_open(&sess2, file_01, sizeof(file_01),
+			TEE_DATA_FLAG_ACCESS_READ, &obj2, storage_id)))
+		goto clean;
+
+	if (storage_id == TEE_STORAGE_PRIVATE_REE) {
+		/*
+		 * When the storage backend is the REE filesystem, we can
+		 * simulate a hack attempt by renaming the TA storage. Should
+		 * be detected by the TEE.
+		 */
+		if (rename_data_dir(&uuid, &uuid2) < 0)
+			goto clean;
+
+		/* TA #2 tries to open the object created by TA #1 */
+		ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_CORRUPT_OBJECT,
+			fs_open(&sess2, file_01, sizeof(file_01),
+				TEE_DATA_FLAG_ACCESS_READ, &obj2, storage_id));
+		/*
+		 * At this point, the TEE is expected to have removed the
+		 * corrupt object, so there is no need to try and restore the
+		 * directory name.
+		 */
+		goto exit;
+	}
+
+clean:
+	ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj));
+exit:
+	TEEC_CloseSession(&sess2);
+exit2:
+	TEEC_CloseSession(&sess);
+}
+
+DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6015)
+
 ADBG_CASE_DEFINE(
 	XTEST_TEE_6001, xtest_tee_test_6001,
 	/* Title */
@@ -1521,3 +1628,15 @@
     /* How to implement */
     "Description of how to implement ..."
 );
+
+ADBG_CASE_DEFINE(
+    XTEST_TEE_6015, xtest_tee_test_6015,
+    /* Title */
+    "Storage isolation",
+    /* Short description */
+    "TA #2 tries to open object created by TA #1, should fail",
+    /* Requirement IDs */
+    "",
+    /* How to implement */
+    ""
+);
diff --git a/host/xtest/xtest_helpers.c b/host/xtest/xtest_helpers.c
index 0ce5c63..7a91acd 100644
--- a/host/xtest/xtest_helpers.c
+++ b/host/xtest/xtest_helpers.c
@@ -381,3 +381,30 @@
 
 	return res;
 }
+
+#define SWAP_BYTES_16(w16) ((((w16) & 0xFF00) >> 8) | (((w16) & 0xFF) << 8))
+#define SWAP_BYTES_32(w32) ((((w32) & 0xFF000000) >> 24) |\
+			    (((w32) & 0xFF0000) >> 8) |\
+			    (((w32) & 0xFF00) << 8) |\
+			    (((w32) & 0xFF) << 24))
+
+int ree_fs_get_ta_dirname(TEEC_UUID *p_uuid, char *buffer, uint32_t len)
+{
+
+	if (p_uuid == NULL || buffer == NULL)
+		return 0;
+
+	return snprintf(buffer, len,
+			"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
+			SWAP_BYTES_32(p_uuid->timeLow),
+			SWAP_BYTES_16(p_uuid->timeMid),
+			SWAP_BYTES_16(p_uuid->timeHiAndVersion),
+			p_uuid->clockSeqAndNode[0],
+			p_uuid->clockSeqAndNode[1],
+			p_uuid->clockSeqAndNode[2],
+			p_uuid->clockSeqAndNode[3],
+			p_uuid->clockSeqAndNode[4],
+			p_uuid->clockSeqAndNode[5],
+			p_uuid->clockSeqAndNode[6],
+			p_uuid->clockSeqAndNode[7]);
+}
diff --git a/host/xtest/xtest_helpers.h b/host/xtest/xtest_helpers.h
index 691fa16..8edee8e 100644
--- a/host/xtest/xtest_helpers.h
+++ b/host/xtest/xtest_helpers.h
@@ -100,4 +100,6 @@
 TEE_Result pack_attrs(const TEE_Attribute *attrs, uint32_t attr_count,
 			     uint8_t **buf, size_t *blen);
 
+int ree_fs_get_ta_dirname(TEEC_UUID *p_uuid, char *buffer, uint32_t len);
+
 #endif /*XTEST_HELPERS_H*/
diff --git a/host/xtest/xtest_main.c b/host/xtest/xtest_main.c
index 88e5734..44c91d8 100644
--- a/host/xtest/xtest_main.c
+++ b/host/xtest/xtest_main.c
@@ -67,6 +67,7 @@
 ADBG_SUITE_ENTRY(XTEST_TEE_6012, NULL)
 ADBG_SUITE_ENTRY(XTEST_TEE_6013, NULL)
 ADBG_SUITE_ENTRY(XTEST_TEE_6014, NULL)
+ADBG_SUITE_ENTRY(XTEST_TEE_6015, NULL)
 ADBG_SUITE_ENTRY(XTEST_TEE_7001, NULL)
 /* FVP    ADBG_SUITE_ENTRY(XTEST_TEE_7002, NULL) */
 ADBG_SUITE_ENTRY(XTEST_TEE_7003, NULL)
diff --git a/host/xtest/xtest_test.c b/host/xtest/xtest_test.c
index 9eb6bc2..fa0d214 100644
--- a/host/xtest/xtest_test.c
+++ b/host/xtest/xtest_test.c
@@ -86,6 +86,7 @@
 const TEEC_UUID rpc_test_ta_uuid = TA_RPC_TEST_UUID;
 const TEEC_UUID sims_test_ta_uuid = TA_SIMS_TEST_UUID;
 const TEEC_UUID storage_ta_uuid = TA_STORAGE_UUID;
+const TEEC_UUID storage2_ta_uuid = TA_STORAGE2_UUID;
 const TEEC_UUID enc_fs_key_manager_test_ta_uuid = ENC_FS_KEY_MANAGER_TEST_UUID;
 const TEEC_UUID concurrent_ta_uuid = TA_CONCURRENT_UUID;
 const TEEC_UUID concurrent_large_ta_uuid = TA_CONCURRENT_LARGE_UUID;
diff --git a/host/xtest/xtest_test.h b/host/xtest/xtest_test.h
index f815335..82db7c2 100644
--- a/host/xtest/xtest_test.h
+++ b/host/xtest/xtest_test.h
@@ -62,6 +62,7 @@
 ADBG_CASE_DECLARE(XTEST_TEE_6012);
 ADBG_CASE_DECLARE(XTEST_TEE_6013);
 ADBG_CASE_DECLARE(XTEST_TEE_6014);
+ADBG_CASE_DECLARE(XTEST_TEE_6015);
 ADBG_CASE_DECLARE(XTEST_TEE_7001);
 ADBG_CASE_DECLARE(XTEST_TEE_7002);
 ADBG_CASE_DECLARE(XTEST_TEE_7003);
@@ -205,6 +206,7 @@
 extern const TEEC_UUID gp_tta_check_OpenSession_with_4_parameters_uuid;
 extern const TEEC_UUID gp_tta_ds_uuid;
 extern const TEEC_UUID storage_ta_uuid;
+extern const TEEC_UUID storage2_ta_uuid;
 extern const TEEC_UUID enc_fs_key_manager_test_ta_uuid;
 extern const TEEC_UUID ecc_test_ta_uuid;
 extern const TEEC_UUID sta_test_ta_uuid;
diff --git a/ta/Makefile b/ta/Makefile
index b162f3f..1cc01be 100644
--- a/ta/Makefile
+++ b/ta/Makefile
@@ -15,6 +15,7 @@
 	   rpc_test \
 	   sims \
 	   storage \
+	   storage2 \
 	   concurrent \
 	   concurrent_large \
 	   storage_benchmark
diff --git a/ta/storage/include/ta_storage.h b/ta/storage/include/ta_storage.h
index abc6119..6f24f5b 100644
--- a/ta/storage/include/ta_storage.h
+++ b/ta/storage/include/ta_storage.h
@@ -30,6 +30,8 @@
 
 #define TA_STORAGE_UUID { 0xb689f2a7, 0x8adf, 0x477a, \
 	{ 0x9f, 0x99, 0x32, 0xe9, 0x0c, 0x0a, 0xd0, 0xa2 } }
+#define TA_STORAGE2_UUID { 0x731e279e, 0xaafb, 0x4575, \
+	{ 0xa7, 0x71, 0x38, 0xca, 0xa6, 0xf0, 0xcc, 0xa6 } }
 
 #define TA_STORAGE_CMD_OPEN			0
 #define TA_STORAGE_CMD_CLOSE			1
diff --git a/ta/storage2/Android.mk b/ta/storage2/Android.mk
new file mode 100644
index 0000000..98230f2
--- /dev/null
+++ b/ta/storage2/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+local_module := 731e279e-aafb-4575-a77138caa6f0cca6.ta
+include $(BUILD_OPTEE_MK)
diff --git a/ta/storage2/Makefile b/ta/storage2/Makefile
new file mode 100644
index 0000000..9f0a307
--- /dev/null
+++ b/ta/storage2/Makefile
@@ -0,0 +1,2 @@
+BINARY = 731e279e-aafb-4575-a77138caa6f0cca6
+include ../ta_common.mk
diff --git a/ta/storage2/include/storage.h b/ta/storage2/include/storage.h
new file mode 100644
index 0000000..da39a88
--- /dev/null
+++ b/ta/storage2/include/storage.h
@@ -0,0 +1 @@
+#include "../storage/include/storage.h"
diff --git a/ta/storage2/include/ta_storage.h b/ta/storage2/include/ta_storage.h
new file mode 100644
index 0000000..eec9871
--- /dev/null
+++ b/ta/storage2/include/ta_storage.h
@@ -0,0 +1 @@
+#include "../storage/include/ta_storage.h"
diff --git a/ta/storage2/include/user_ta_header_defines.h b/ta/storage2/include/user_ta_header_defines.h
new file mode 100644
index 0000000..c04ab0b
--- /dev/null
+++ b/ta/storage2/include/user_ta_header_defines.h
@@ -0,0 +1,17 @@
+#ifndef USER_TA_HEADER_DEFINES_H
+#define USER_TA_HEADER_DEFINES_H
+
+#include "ta_storage.h"
+
+#define TA_UUID TA_STORAGE2_UUID
+
+/*
+ * This is important to have TA_FLAG_SINGLE_INSTANCE && !TA_FLAG_MULTI_SESSION
+ * as it is used by the ytest
+ */
+#define TA_FLAGS		(TA_FLAG_USER_MODE | TA_FLAG_EXEC_DDR | \
+				TA_FLAG_SINGLE_INSTANCE)
+#define TA_STACK_SIZE		(2 * 1024)
+#define TA_DATA_SIZE		(32 * 1024)
+
+#endif
diff --git a/ta/storage2/storage.c b/ta/storage2/storage.c
new file mode 100644
index 0000000..a6070b5
--- /dev/null
+++ b/ta/storage2/storage.c
@@ -0,0 +1 @@
+#include "../storage/storage.c"
diff --git a/ta/storage2/sub.mk b/ta/storage2/sub.mk
new file mode 100644
index 0000000..c5a00cb
--- /dev/null
+++ b/ta/storage2/sub.mk
@@ -0,0 +1,3 @@
+global-incdirs-y += include
+srcs-y += storage.c
+srcs-y += ta_entry.c
diff --git a/ta/storage2/ta_entry.c b/ta/storage2/ta_entry.c
new file mode 100644
index 0000000..993605c
--- /dev/null
+++ b/ta/storage2/ta_entry.c
@@ -0,0 +1 @@
+#include "../storage/ta_entry.c"