From e3ff5f4e225c49e2ce31036749f9a3adc3e96f81 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Mon, 7 Oct 2024 15:22:02 +0200 Subject: [PATCH] xtest: sdp_basic: use TEE_IOC_RSTMEM_ALLOC Use the new TEE IOCTL TEE_IOC_RSTMEM_ALLOC to allocate restricted buffers for Secure Data Path tests. Signed-off-by: Jens Wiklander --- host/xtest/sdp_basic.c | 213 ++++++++++++++++++++++++++--------------- 1 file changed, 137 insertions(+), 76 deletions(-) diff --git a/host/xtest/sdp_basic.c b/host/xtest/sdp_basic.c index 45a7c0eb5..f5f58d587 100644 --- a/host/xtest/sdp_basic.c +++ b/host/xtest/sdp_basic.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include "crypto_common.h" #include "sdp_basic.h" @@ -56,6 +58,44 @@ struct tee_ctx { TEEC_Session sess; }; +#ifndef TEE_IOC_RSTMEM_ALLOC + +#define TEE_IOC_UC_RESERVED 0 +#define TEE_IOC_UC_SECURE_VIDEO_PLAY 1 +#define TEE_IOC_UC_TRUSTED_UI 2 +#define TEE_IOC_UC_SECURE_VIDEO_RECORD 3 + + +/** + * struct tee_ioctl_rstmem_alloc_data - Restricted memory allocate argument + * @size: [in/out] Size of restricted memory to allocate + * @flags: [in/out] Flags to/from allocate + * @use_case [in] Restricted memroy use case, TEE_IOC_UC_* + * @id: [out] Identifier of the restricted memory + */ +struct tee_ioctl_rstmem_alloc_data { + __u64 size; + __u32 flags; + __u32 use_case; + __s32 id; +}; + +/** + * TEE_IOC_RSTMEM_ALLOC - allocate restricted memory + * + * Allocates restricted physically memory normally not accessible by the + * kernel. + * + * Returns a file descriptor on success or < 0 on failure + * + * The returned file descriptor is a dma-buf that can be attached and + * mapped for device with permission to access the physical memory. + */ +#define TEE_IOC_RSTMEM_ALLOC _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 10, \ + struct tee_ioctl_rstmem_alloc_data) +#endif + + int allocate_dma_buffer(size_t size, const char *heap_name, int verbosity) { const char *default_dev = DEFAULT_HEAP_NAME; @@ -90,6 +130,53 @@ int allocate_dma_buffer(size_t size, const char *heap_name, int verbosity) return fd; } +static int rmem_alloc(int fd, size_t size, int *id) +{ + struct tee_ioctl_rstmem_alloc_data data = { + .size = size, + .use_case = TEE_IOC_UC_SECURE_VIDEO_PLAY, + }; + int rmem_fd = 0; + + rmem_fd = ioctl(fd, TEE_IOC_RSTMEM_ALLOC, &data); + if (rmem_fd >= 0) + *id = data.id; + return rmem_fd; +} + +static TEEC_Result TEEC_AllocateRestrictedMemory(TEEC_Context *ctx, TEEC_SharedMemory *shm) +{ + size_t s = 0; + int fd = 0; + + warn("%s: hej 1\n", __func__); + if (!ctx || !shm) + return TEEC_ERROR_BAD_PARAMETERS; + + warn("%s: hej 2\n", __func__); + if (!shm->flags || (shm->flags & ~(TEEC_MEM_INPUT | TEEC_MEM_OUTPUT))) + return TEEC_ERROR_BAD_PARAMETERS; + + warn("%s: hej 3\n", __func__); + s = shm->size; + if (!s) + s = 8; + + fd = rmem_alloc(ctx->imp.fd, s, &shm->imp.id); + if (fd < 0) { + warn("%s: hej 4\n", __func__); + if (errno == ENOMEM) + return TEEC_ERROR_OUT_OF_MEMORY; + warn("%s: hej 6\n", __func__); + return TEEC_ERROR_NOT_SUPPORTED; + } + + shm->imp.registered_fd = fd; + warn("%s: hej 7\n", __func__); + + return TEEC_SUCCESS; +} + static void finalize_tee_ctx(struct tee_ctx *ctx) { if (!ctx) @@ -134,37 +221,6 @@ static int create_tee_ctx(struct tee_ctx *ctx, enum test_target_ta target_ta) return (teerc == TEEC_SUCCESS) ? 0 : -1; } -static int tee_register_buffer(struct tee_ctx *ctx, void **shm_ref, int fd) -{ - TEEC_Result teerc = TEEC_ERROR_GENERIC; - TEEC_SharedMemory *shm = malloc(sizeof(*shm)); - - if (!shm) - return 1; - - shm->flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; - teerc = TEEC_RegisterSharedMemoryFileDescriptor(&ctx->ctx, shm, fd); - if (teerc != TEEC_SUCCESS) { - fprintf(stderr, "Error: TEEC_RegisterMemoryFileDescriptor() failed %x\n", - teerc); - return 1; - } - - *shm_ref = shm; - return 0; -} - -static void tee_deregister_buffer(struct tee_ctx *ctx, void *shm_ref) -{ - (void)ctx; - - if (!shm_ref) - return; - - TEEC_ReleaseSharedMemory((TEEC_SharedMemory *)shm_ref); - free(shm_ref); -} - static int inject_sdp_data(struct tee_ctx *ctx, void *in, size_t offset, size_t len, void *shm_ref, int ind) { @@ -371,12 +427,12 @@ static int get_random_bytes(char *out, size_t len) int sdp_basic_test(enum test_target_ta ta, size_t size, size_t loop, const char *heap_name, int rnd_offset, int verbosity) { + TEEC_Result res; struct tee_ctx *ctx = NULL; unsigned char *test_buf = NULL; unsigned char *ref_buf = NULL; - void *shm_ref = NULL; + TEEC_SharedMemory shm = { }; unsigned int err = 1; - int fd = -1; size_t sdp_size = size; size_t offset = 0; size_t loop_cnt = 0; @@ -394,65 +450,63 @@ int sdp_basic_test(enum test_target_ta ta, size_t size, size_t loop, ref_buf = malloc(size); if (!test_buf || !ref_buf) { verbose("failed to allocate memory\n"); - goto bail1; + goto out_free; } - fd = allocate_buffer(sdp_size, heap_name, verbosity); - if (fd < 0) { - verbose("Failed to allocate SDP buffer (%zu bytes) in %s: %d\n", - sdp_size, heap_name, fd); - goto bail1; - } - - /* register secure buffer to TEE */ ctx = malloc(sizeof(*ctx)); if (!ctx) - goto bail1; + goto out_free; if (create_tee_ctx(ctx, ta)) - goto bail1; - if (tee_register_buffer(ctx, &shm_ref, fd)) - goto bail2; - - /* release registered fd: tee should still hold refcount on resource */ - close(fd); - fd = -1; + goto out_free; + shm.size = sdp_size; + shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; + res = TEEC_AllocateRestrictedMemory(&ctx->ctx, &shm); + if (res) { + verbose("Failed to allocate SDP buffer (%zu bytes)\n", + sdp_size); + goto out_finalize_ctx; + } /* invoke trusted application with secure buffer as memref parameter */ for (loop_cnt = loop; loop_cnt; loop_cnt--) { /* get an buffer of random-like values */ if (get_random_bytes((char *)ref_buf, size)) - goto bail2; + goto out_rel_shm; memcpy(test_buf, ref_buf, size); /* random offset [0 255] */ offset = (unsigned int)*ref_buf; /* TA writes into SDP buffer */ - if (inject_sdp_data(ctx, test_buf, offset, size, shm_ref, ta)) - goto bail2; + if (inject_sdp_data(ctx, test_buf, offset, size, &shm, ta)) { + fprintf(stderr, "err1\n"); + goto out_rel_shm; + } /* TA reads/writes into SDP buffer */ - if (transform_sdp_data(ctx, offset, size, shm_ref, ta)) - goto bail2; + if (transform_sdp_data(ctx, offset, size, &shm, ta)) { + fprintf(stderr, "err2\n"); + goto out_rel_shm; + } /* TA reads into SDP buffer */ - if (dump_sdp_data(ctx, test_buf, offset, size, shm_ref, ta)) - goto bail2; + if (dump_sdp_data(ctx, test_buf, offset, size, &shm, ta)) { + fprintf(stderr, "err3\n"); + goto out_rel_shm; + } /* check dumped data are the expected ones */ if (check_sdp_dumped(ctx, ref_buf, size, test_buf)) { fprintf(stderr, "check SDP data: %d errors\n", err); - goto bail2; + goto out_rel_shm; } } err = 0; -bail2: - if (fd >= 0) - close(fd); - if (shm_ref) - tee_deregister_buffer(ctx, shm_ref); +out_rel_shm: + TEEC_ReleaseSharedMemory(&shm); +out_finalize_ctx: finalize_tee_ctx(ctx); -bail1: +out_free: free(ctx); free(ref_buf); free(test_buf); @@ -517,14 +571,14 @@ int sdp_out_of_bounds_memref_test(size_t size, const char *heap_name, { struct tee_ctx ctx = { }; int err = 0; - int fd = -1; TEEC_Result teerc = TEEC_ERROR_GENERIC; TEEC_SharedMemory in = { }; - TEEC_SharedMemory *out = NULL; + TEEC_SharedMemory out = { }; if (create_tee_ctx(&ctx, TEST_NS_TO_TA)) return -1; +#if 0 fd = allocate_buffer(size, heap_name, verbosity); if (fd < 0) { verbose("SDP alloc failed (%zu bytes) in %s: %d\n", @@ -536,12 +590,21 @@ int sdp_out_of_bounds_memref_test(size_t size, const char *heap_name, err = 1; goto bail; } +#else + out.size = size; + out.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; + teerc = TEEC_AllocateRestrictedMemory(&ctx.ctx, &out); + if (teerc) { + verbose("failed to allocate memory\n"); + goto bail; + } +#endif /* * The ION driver will decide how much SDP memory is being allocated. * Rely on this size to test out of bounds reference cases. */ - size = out->size; + size = out.size; in.size = size; in.flags = TEEC_MEM_INPUT; @@ -553,35 +616,33 @@ int sdp_out_of_bounds_memref_test(size_t size, const char *heap_name, if (verbosity) { /* Valid case: reference inside allocated buffer: last byte */ - err += invoke_out_of_bounds(&ctx, &in, out, size - 1, 1, + err += invoke_out_of_bounds(&ctx, &in, &out, size - 1, 1, true, verbosity); } /* Reference overflows allocated buffer by 1 byte */ - err += invoke_out_of_bounds(&ctx, &in, out, size - 1, 2, + err += invoke_out_of_bounds(&ctx, &in, &out, size - 1, 2, false, verbosity); /* Reference oveflows allocated buffer by more than 4kB byte */ - err += invoke_out_of_bounds(&ctx, &in, out, size - 1, 5000, + err += invoke_out_of_bounds(&ctx, &in, &out, size - 1, 5000, false, verbosity); /* Offset exceeds allocated buffer size value by 1 byte */ - err += invoke_out_of_bounds(&ctx, &in, out, size, 1, + err += invoke_out_of_bounds(&ctx, &in, &out, size, 1, false, verbosity); /* Offset exceeds allocated size value by 4kByte */ - err += invoke_out_of_bounds(&ctx, &in, out, size, 4096, + err += invoke_out_of_bounds(&ctx, &in, &out, size, 4096, false, verbosity); /* Offset + size overflows offset value */ - err += invoke_out_of_bounds(&ctx, &in, out, 2, ~0, + err += invoke_out_of_bounds(&ctx, &in, &out, 2, ~0, false, verbosity); TEEC_ReleaseSharedMemory(&in); bail: - tee_deregister_buffer(&ctx, out); - if (fd >= 0) - close(fd); + TEEC_ReleaseSharedMemory(&out); finalize_tee_ctx(&ctx); return err;