From 26a1dd295451cdda4f1921f70c69b056cbfd689d Mon Sep 17 00:00:00 2001 From: Sungbae Yoo Date: Wed, 12 Aug 2026 04:04:51 +0000 Subject: [PATCH 1/2] core: tee_ree_fs: avoid narrowing file positions REE FS supports file positions up to TEE_DATA_MAX_POSITION (0xffffffff), but pos_to_block_num() accepted int. Positions above INT_MAX (0x7fffffff) were narrowed when converted to block numbers. Use size_t for the conversion and block numbers in the read and write paths. Fixes: a238b744b1b3 ("core: REE FS: use the new hash tree interface") Signed-off-by: Sungbae Yoo Reviewed-by: Jens Wiklander --- core/tee/tee_ree_fs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/tee/tee_ree_fs.c b/core/tee/tee_ree_fs.c index e698e9c82ca..be308b18e2f 100644 --- a/core/tee/tee_ree_fs.c +++ b/core/tee/tee_ree_fs.c @@ -44,7 +44,7 @@ struct tee_fs_dir { const TEE_UUID *uuid; }; -static int pos_to_block_num(int position) +static size_t pos_to_block_num(size_t position) { return position >> BLOCK_SHIFT; } @@ -318,8 +318,8 @@ static TEE_Result ree_fs_read_primitive(struct tee_file_handle *fh, size_t pos, size_t *len) { TEE_Result res; - int start_block_num; - int end_block_num; + size_t start_block_num = 0; + size_t end_block_num = 0; size_t remain_bytes; uint8_t *data_core_ptr = buf_core; uint8_t *data_user_ptr = buf_user; From 85e7358cafa87eece1c7e84799a868110b338baa Mon Sep 17 00:00:00 2001 From: Sungbae Yoo Date: Wed, 12 Aug 2026 04:05:24 +0000 Subject: [PATCH 2/2] core: tee_ree_fs: preserve physical offsets on 32-bit builds REE FS backing file offsets can exceed 4 GiB within the valid logical position range. However, get_offs_size() stored physical offsets in size_t. On 32-bit builds, offsets above SIZE_MAX (0xffffffff) therefore wrapped before being passed to the 64-bit read and write RPC interface. The truncate length could wrap in the same way. Calculate physical offsets with 64-bit arithmetic and carry them as tee_fs_off_t through read, write, and truncate RPC requests. Fixes: a238b744b1b3 ("core: REE FS: use the new hash tree interface") Signed-off-by: Sungbae Yoo Reviewed-by: Jens Wiklander --- core/include/tee/tee_fs_rpc.h | 2 +- core/tee/tee_fs_rpc.c | 5 ++++- core/tee/tee_ree_fs.c | 21 +++++++++++---------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/core/include/tee/tee_fs_rpc.h b/core/include/tee/tee_fs_rpc.h index 88132952c20..ca15c6a20cb 100644 --- a/core/include/tee/tee_fs_rpc.h +++ b/core/include/tee/tee_fs_rpc.h @@ -43,7 +43,7 @@ TEE_Result tee_fs_rpc_write_init(struct tee_fs_rpc_operation *op, TEE_Result tee_fs_rpc_write_final(struct tee_fs_rpc_operation *op); -TEE_Result tee_fs_rpc_truncate(uint32_t id, int fd, size_t len); +TEE_Result tee_fs_rpc_truncate(uint32_t id, int fd, tee_fs_off_t len); TEE_Result tee_fs_rpc_remove_dfh(uint32_t id, const struct tee_fs_dirfile_fileh *dfh); #endif /* __TEE_TEE_FS_RPC_H */ diff --git a/core/tee/tee_fs_rpc.c b/core/tee/tee_fs_rpc.c index 8066841e4f9..e62cd7e004c 100644 --- a/core/tee/tee_fs_rpc.c +++ b/core/tee/tee_fs_rpc.c @@ -177,7 +177,7 @@ TEE_Result tee_fs_rpc_write_final(struct tee_fs_rpc_operation *op) return operation_commit(op); } -TEE_Result tee_fs_rpc_truncate(uint32_t id, int fd, size_t len) +TEE_Result tee_fs_rpc_truncate(uint32_t id, int fd, tee_fs_off_t len) { struct tee_fs_rpc_operation op = { .id = id, .num_params = 1, .params = { @@ -186,6 +186,9 @@ TEE_Result tee_fs_rpc_truncate(uint32_t id, int fd, size_t len) } }; + if (len < 0) + return TEE_ERROR_BAD_PARAMETERS; + return operation_commit(&op); } diff --git a/core/tee/tee_ree_fs.c b/core/tee/tee_ree_fs.c index be308b18e2f..526895c259f 100644 --- a/core/tee/tee_ree_fs.c +++ b/core/tee/tee_ree_fs.c @@ -142,12 +142,13 @@ static TEE_Result out_of_place_write(struct tee_fs_fd *fdp, size_t pos, } static TEE_Result get_offs_size(enum tee_fs_htree_type type, size_t idx, - uint8_t vers, size_t *offs, size_t *size) + uint8_t vers, tee_fs_off_t *offs, size_t *size) { const size_t node_size = sizeof(struct tee_fs_htree_node_image); const size_t block_nodes = BLOCK_SIZE / (node_size * 2); - size_t pbn; - size_t bidx; + const uint64_t idx64 = idx; + uint64_t pbn = 0; + uint64_t bidx = 0; assert(vers == 0 || vers == 1); @@ -207,14 +208,14 @@ static TEE_Result get_offs_size(enum tee_fs_htree_type type, size_t idx, *size = sizeof(struct tee_fs_htree_image); return TEE_SUCCESS; case TEE_FS_HTREE_TYPE_NODE: - pbn = 1 + ((idx / block_nodes) * block_nodes * 2); + pbn = 1 + (idx64 / block_nodes) * block_nodes * 2; *offs = pbn * BLOCK_SIZE + - 2 * node_size * (idx % block_nodes) + + 2 * node_size * (idx64 % block_nodes) + node_size * vers; *size = node_size; return TEE_SUCCESS; case TEE_FS_HTREE_TYPE_BLOCK: - bidx = 2 * idx + vers; + bidx = 2 * idx64 + vers; pbn = 2 + bidx + bidx / (block_nodes * 2 - 1); *offs = pbn * BLOCK_SIZE; *size = BLOCK_SIZE; @@ -231,7 +232,7 @@ static TEE_Result ree_fs_rpc_read_init(void *aux, { struct tee_fs_fd *fdp = aux; TEE_Result res; - size_t offs; + tee_fs_off_t offs = 0; size_t size; res = get_offs_size(type, idx, vers, &offs, &size); @@ -249,7 +250,7 @@ static TEE_Result ree_fs_rpc_write_init(void *aux, { struct tee_fs_fd *fdp = aux; TEE_Result res; - size_t offs; + tee_fs_off_t offs = 0; size_t size; res = get_offs_size(type, idx, vers, &offs, &size); @@ -287,7 +288,7 @@ static TEE_Result ree_fs_ftruncate_internal(struct tee_fs_fd *fdp, if (res != TEE_SUCCESS) return res; } else { - size_t offs; + tee_fs_off_t offs = 0; size_t sz; res = get_offs_size(TEE_FS_HTREE_TYPE_BLOCK, @@ -302,7 +303,7 @@ static TEE_Result ree_fs_ftruncate_internal(struct tee_fs_fd *fdp, return res; res = tee_fs_rpc_truncate(OPTEE_RPC_CMD_FS, fdp->fd, - offs + sz); + offs + (tee_fs_off_t)sz); if (res != TEE_SUCCESS) return res;