summaryrefslogtreecommitdiff
path: root/core/tee
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2016-10-18 17:07:22 +0200
committerJens Wiklander <jens.wiklander@linaro.org>2016-10-25 12:44:00 +0200
commit850c8ebb05d57009ea1bc974269e1ab50f037017 (patch)
tree2f7e0e12a0aca79c261de90ac25783f082738b67 /core/tee
parent621564da3a94abeb2d68b17601ec1c3063d6f670 (diff)
core: SQL FS: use new RPC functions
SQL FS is simlified by using the new RPC functions instead of the legacy open/read/write/close. Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org> Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'core/tee')
-rw-r--r--core/tee/tee_sql_fs.c431
1 files changed, 158 insertions, 273 deletions
diff --git a/core/tee/tee_sql_fs.c b/core/tee/tee_sql_fs.c
index acc1639d..83f161a4 100644
--- a/core/tee/tee_sql_fs.c
+++ b/core/tee/tee_sql_fs.c
@@ -115,11 +115,6 @@ static struct tee_fs_dir *sql_fs_opendir_rpc(const char *name)
return tee_fs_rpc_opendir(OPTEE_MSG_RPC_CMD_SQL_FS, name);
}
-static int sql_fs_read_rpc(int fd, void *buf, size_t len)
-{
- return tee_fs_rpc_read(OPTEE_MSG_RPC_CMD_SQL_FS, fd, buf, len);
-}
-
static struct tee_fs_dirent *sql_fs_readdir_rpc(struct tee_fs_dir *d)
{
return tee_fs_rpc_readdir(OPTEE_MSG_RPC_CMD_SQL_FS, d);
@@ -130,11 +125,6 @@ static int sql_fs_rename_rpc(const char *old, const char *nw)
return tee_fs_rpc_rename(OPTEE_MSG_RPC_CMD_SQL_FS, old, nw);
}
-static int sql_fs_write_rpc(int fd, const void *buf, size_t len)
-{
- return tee_fs_rpc_write(OPTEE_MSG_RPC_CMD_SQL_FS, fd, buf, len);
-}
-
static int sql_fs_closedir_rpc(struct tee_fs_dir *d)
{
return tee_fs_rpc_closedir(OPTEE_MSG_RPC_CMD_SQL_FS, d);
@@ -147,7 +137,11 @@ static int sql_fs_rmdir_rpc(const char *name)
static int sql_fs_unlink_rpc(const char *file)
{
- return tee_fs_rpc_unlink(OPTEE_MSG_RPC_CMD_SQL_FS, file);
+ TEE_Result res = tee_fs_rpc_new_remove(OPTEE_MSG_RPC_CMD_SQL_FS, file);
+
+ if (res != TEE_SUCCESS)
+ return -1;
+ return 0;
}
/*
@@ -176,103 +170,36 @@ static ssize_t block_num(tee_fs_off_t pos)
return pos / BLOCK_SIZE;
}
-/* Return the block number from a position in the DB file */
-static ssize_t block_num_raw(tee_fs_off_t raw_pos)
-{
- return (raw_pos - meta_size()) / block_size_raw();
-}
-
/* Return the position of a block in the DB file */
static ssize_t block_pos_raw(size_t block_num)
{
return meta_size() + block_num * block_size_raw();
}
-/* Given a position in the user data, return the offset in the DB file */
-static tee_fs_off_t pos_to_raw(tee_fs_off_t pos)
+static TEE_Result write_meta(struct sql_fs_fd *fdp)
{
- tee_fs_off_t res;
-
- if (pos < 0)
- return -1;
- res = meta_size() + block_num(pos) * block_size_raw();
- if (pos % BLOCK_SIZE) {
- res += block_header_size();
- res += pos % BLOCK_SIZE;
- }
-
- return res;
-}
-
-/* Given a position in the DB file, return the offset in the user data */
-static tee_fs_off_t raw_to_pos(tee_fs_off_t raw_pos)
-{
- tee_fs_off_t pos = raw_pos;
- ssize_t n = block_num_raw(raw_pos);
-
- if (n < 0)
- return -1;
-
- pos -= meta_size();
- pos -= block_header_size();
- if (pos < 0)
- return -1;
-
- return (n * BLOCK_SIZE) + (pos % BLOCK_SIZE);
-}
-
-static void put_fdp(struct sql_fs_fd *fdp)
-{
- handle_put(&fs_db, fdp->fd);
- free(fdp);
-}
-
-static int write_meta(TEE_Result *errno, struct sql_fs_fd *fdp)
-{
- int fd = fdp->fd;
+ TEE_Result res;
size_t ct_size = meta_size();
- uint8_t *ct;
- int rc = -1;
-
- *errno = TEE_ERROR_GENERIC;
-
- ct = malloc(ct_size);
- if (!ct) {
- *errno = TEE_ERROR_OUT_OF_MEMORY;
- goto exit;
- }
+ void *ct;
+ struct tee_fs_rpc_operation op;
- rc = tee_fs_rpc_lseek(OPTEE_MSG_RPC_CMD_SQL_FS, fd, 0,
- TEE_FS_SEEK_SET);
- if (rc < 0)
- goto exit;
+ res = tee_fs_rpc_new_write_init(&op, OPTEE_MSG_RPC_CMD_SQL_FS,
+ fdp->fd, 0, ct_size, &ct);
+ if (res != TEE_SUCCESS)
+ return res;
- {
- TEE_Result res;
- res = tee_fs_encrypt_file(META_FILE,
- (const uint8_t *)&fdp->meta,
- sizeof(fdp->meta), ct, &ct_size,
- fdp->encrypted_fek);
- if (res != TEE_SUCCESS) {
- *errno = res;
- rc = -1;
- goto exit;
- }
- }
-
- rc = sql_fs_write_rpc(fdp->fd, ct, ct_size);
- if (rc != (int)ct_size)
- rc = -1;
- else
- rc = 0;
+ res = tee_fs_encrypt_file(META_FILE,
+ (const uint8_t *)&fdp->meta,
+ sizeof(fdp->meta), ct, &ct_size,
+ fdp->encrypted_fek);
+ if (res != TEE_SUCCESS)
+ return res;
-exit:
- free(ct);
- return rc;
+ return tee_fs_rpc_new_write_final(&op);
}
-static int create_meta(TEE_Result *errno, struct sql_fs_fd *fdp)
+static TEE_Result create_meta(struct sql_fs_fd *fdp, const char *fname)
{
TEE_Result res;
@@ -280,66 +207,42 @@ static int create_meta(TEE_Result *errno, struct sql_fs_fd *fdp)
res = tee_fs_generate_fek(fdp->encrypted_fek, TEE_FS_KM_FEK_SIZE);
if (res != TEE_SUCCESS)
- return -1;
+ return res;
- return write_meta(errno, fdp);
+ res = tee_fs_rpc_new_create(OPTEE_MSG_RPC_CMD_SQL_FS, fname, &fdp->fd);
+ if (res != TEE_SUCCESS)
+ return res;
+
+ return write_meta(fdp);
}
-/*
- * Read metadata block from disk, possibly create it if it does not exist and
- * and open flags allow
- */
-static int read_meta(TEE_Result *errno, struct sql_fs_fd *fdp)
+static TEE_Result read_meta(struct sql_fs_fd *fdp, const char *fname)
{
+ TEE_Result res;
size_t msize = meta_size();
size_t out_size = sizeof(fdp->meta);
- uint8_t *meta = NULL;
- int rc = -1;
+ void *meta;
+ size_t bytes;
+ struct tee_fs_rpc_operation op;
- *errno = TEE_ERROR_GENERIC;
-
- meta = malloc(msize);
- if (!meta) {
- *errno = TEE_ERROR_OUT_OF_MEMORY;
- goto exit;
- }
+ res = tee_fs_rpc_new_open(OPTEE_MSG_RPC_CMD_SQL_FS, fname, &fdp->fd);
+ if (res != TEE_SUCCESS)
+ return res;
- rc = tee_fs_rpc_lseek(OPTEE_MSG_RPC_CMD_SQL_FS, fdp->fd, 0,
- TEE_FS_SEEK_SET);
- if (rc < 0)
- goto exit;
+ res = tee_fs_rpc_new_read_init(&op, OPTEE_MSG_RPC_CMD_SQL_FS,
+ fdp->fd, 0, msize, &meta);
+ if (res != TEE_SUCCESS)
+ return res;
- rc = sql_fs_read_rpc(fdp->fd, meta, msize);
- if (rc < 0) {
- /* Read error */
- goto exit;
- } else if (rc == 0) {
- /* No meta data on disk yet */
- if (!(fdp->flags & TEE_FS_O_CREATE))
- goto exit;
- rc = create_meta(errno, fdp);
- } else if (rc == (int)msize) {
- TEE_Result res;
+ res = tee_fs_rpc_new_read_final(&op, &bytes);
+ if (res != TEE_SUCCESS)
+ return res;
- res = tee_fs_decrypt_file(META_FILE, meta, msize,
- (uint8_t *)&fdp->meta, &out_size,
- fdp->encrypted_fek);
- if (res != TEE_SUCCESS) {
- *errno = res;
- rc = -1;
- goto exit;
- }
- rc = 0;
- } else {
- /* Unexpected data length */
- rc = -1;
- }
-exit:
- free(meta);
- return rc;
+ return tee_fs_decrypt_file(META_FILE, meta, msize,
+ (uint8_t *)&fdp->meta, &out_size,
+ fdp->encrypted_fek);
}
-
/*
* Read one block of user data.
* Returns:
@@ -350,95 +253,69 @@ exit:
static int read_block(TEE_Result *errno, struct sql_fs_fd *fdp, size_t bnum,
uint8_t *data)
{
+ TEE_Result res;
size_t ct_size = block_size_raw();
size_t out_size = BLOCK_SIZE;
ssize_t pos = block_pos_raw(bnum);
- uint8_t *ct = NULL;
- int rc = -1;
-
- ct = malloc(ct_size);
- if (!ct) {
- *errno = TEE_ERROR_OUT_OF_MEMORY;
- goto exit;
- }
-
- rc = tee_fs_rpc_lseek(OPTEE_MSG_RPC_CMD_SQL_FS, fdp->fd, pos,
- TEE_FS_SEEK_SET);
- if (rc < 0) {
- *errno = TEE_ERROR_GENERIC;
- goto exit;
- }
-
- rc = sql_fs_read_rpc(fdp->fd, ct, ct_size);
- if (rc < 0) {
- *errno = TEE_ERROR_GENERIC;
- goto exit;
+ size_t bytes;
+ void *ct;
+ struct tee_fs_rpc_operation op;
+
+ res = tee_fs_rpc_new_read_init(&op, OPTEE_MSG_RPC_CMD_SQL_FS,
+ fdp->fd, pos, ct_size, &ct);
+ if (res != TEE_SUCCESS) {
+ *errno = res;
+ return -1;
}
- if (rc == 0) {
- /* Block does not exist */
- goto exit;
+ res = tee_fs_rpc_new_read_final(&op, &bytes);
+ if (res != TEE_SUCCESS) {
+ *errno = res;
+ return -1;
}
+ if (!bytes)
+ return 0; /* Block does not exist */
- {
- TEE_Result res;
-
- res = tee_fs_decrypt_file(BLOCK_FILE, ct, ct_size, data,
- &out_size, fdp->encrypted_fek);
- if (res != TEE_SUCCESS) {
- *errno = res;
- rc = -1;
- goto exit;
- }
+ res = tee_fs_decrypt_file(BLOCK_FILE, ct, bytes, data,
+ &out_size, fdp->encrypted_fek);
+ if (res != TEE_SUCCESS) {
+ *errno = res;
+ return -1;
}
-exit:
- free(ct);
- return rc;
+ return 1;
}
/* Write one block of user data */
static int write_block(TEE_Result *errno, struct sql_fs_fd *fdp,
size_t bnum, uint8_t *data)
{
+ TEE_Result res;
size_t ct_size = block_size_raw();
ssize_t pos = block_pos_raw(bnum);
- uint8_t *ct = NULL;
- int rc = -1;
-
- ct = malloc(ct_size);
- if (!ct) {
- *errno = TEE_ERROR_OUT_OF_MEMORY;
- goto exit;
- }
+ void *ct;
+ struct tee_fs_rpc_operation op;
- rc = tee_fs_rpc_lseek(OPTEE_MSG_RPC_CMD_SQL_FS, fdp->fd, pos,
- TEE_FS_SEEK_SET);
- if (rc < 0) {
- *errno = TEE_ERROR_GENERIC;
- goto exit;
+ res = tee_fs_rpc_new_write_init(&op, OPTEE_MSG_RPC_CMD_SQL_FS,
+ fdp->fd, pos, ct_size, &ct);
+ if (res != TEE_SUCCESS) {
+ *errno = res;
+ return -1;
}
- {
- TEE_Result res;
-
- res = tee_fs_encrypt_file(BLOCK_FILE, data, BLOCK_SIZE, ct,
- &ct_size, fdp->encrypted_fek);
- if (res != TEE_SUCCESS) {
- *errno = res;
- rc = -1;
- goto exit;
- }
+ res = tee_fs_encrypt_file(BLOCK_FILE, data, BLOCK_SIZE, ct,
+ &ct_size, fdp->encrypted_fek);
+ if (res != TEE_SUCCESS) {
+ *errno = res;
+ return -1;
}
- rc = sql_fs_write_rpc(fdp->fd, ct, ct_size);
- if (rc < 0) {
- *errno = TEE_ERROR_GENERIC;
- goto exit;
+ res = tee_fs_rpc_new_write_final(&op);
+ if (res != TEE_SUCCESS) {
+ *errno = res;
+ return -1;
}
-exit:
- free(ct);
- return rc;
+ return 1;
}
/*
@@ -481,23 +358,15 @@ exit:
return rc;
}
-static int sql_fs_ftruncate_internal(TEE_Result *errno, int fd,
+static int sql_fs_ftruncate_internal(TEE_Result *errno, struct sql_fs_fd *fdp,
tee_fs_off_t new_length)
{
- struct sql_fs_fd *fdp;
+ TEE_Result res;
tee_fs_off_t old_length;
int rc = -1;
- DMSG("(fd: %d, new_length: %" PRId64 ")...", fd, new_length);
-
*errno = TEE_ERROR_GENERIC;
- fdp = handle_lookup(&fs_db, fd);
- if (!fdp) {
- *errno = TEE_ERROR_BAD_PARAMETERS;
- goto exit_ret;
- }
-
old_length = (tee_fs_off_t)fdp->meta.length;
if (new_length == old_length) {
@@ -515,10 +384,13 @@ static int sql_fs_ftruncate_internal(TEE_Result *errno, int fd,
if (last_block < old_last_block) {
off = block_pos_raw(last_block);
- rc = tee_fs_rpc_ftruncate(OPTEE_MSG_RPC_CMD_SQL_FS,
- fd, off);
- if (rc < 0)
+ res = tee_fs_rpc_new_truncate(OPTEE_MSG_RPC_CMD_SQL_FS,
+ fdp->fd, off);
+ if (res != TEE_SUCCESS) {
+ *errno = res;
+ rc = -1;
goto exit;
+ }
}
} else {
/* Extend file with zeroes */
@@ -539,12 +411,15 @@ static int sql_fs_ftruncate_internal(TEE_Result *errno, int fd,
}
fdp->meta.length = new_length;
- rc = write_meta(errno, fdp);
-
+ res = write_meta(fdp);
+ if (res != TEE_SUCCESS) {
+ *errno = res;
+ rc = -1;
+ }
+ rc = 0;
exit:
sql_fs_end_transaction_rpc(rc < 0);
exit_ret:
- DMSG("...%d", rc);
return rc;
}
@@ -553,7 +428,6 @@ static tee_fs_off_t sql_fs_lseek(TEE_Result *errno, int fd,
{
struct sql_fs_fd *fdp;
tee_fs_off_t ret = -1;
- tee_fs_off_t raw_pos;
tee_fs_off_t pos;
DMSG("(fd: %d, offset: %" PRId64 ", whence: %d)...", fd, offset,
@@ -567,8 +441,6 @@ static tee_fs_off_t sql_fs_lseek(TEE_Result *errno, int fd,
if (!fdp)
goto exit_ret;
- sql_fs_begin_transaction_rpc();
-
switch (whence) {
case TEE_FS_SEEK_SET:
pos = offset;
@@ -584,22 +456,20 @@ static tee_fs_off_t sql_fs_lseek(TEE_Result *errno, int fd,
default:
*errno = TEE_ERROR_BAD_PARAMETERS;
- goto exit;
+ goto exit_ret;
}
- raw_pos = pos_to_raw(pos);
- if (raw_pos < 0)
- goto exit;
- raw_pos = tee_fs_rpc_lseek(OPTEE_MSG_RPC_CMD_SQL_FS, fd, raw_pos,
- TEE_FS_SEEK_SET);
- if (raw_pos < 0)
- goto exit;
- ret = raw_to_pos(raw_pos);
- if (ret < 0)
- goto exit;
+ if (pos > TEE_DATA_MAX_POSITION) {
+ EMSG("Position is beyond TEE_DATA_MAX_POSITION");
+ *errno = TEE_ERROR_BAD_PARAMETERS;
+ goto exit_ret;
+ }
+
+ if (pos < 0)
+ ret = 0;
+ else
+ ret = pos;
-exit:
- sql_fs_end_transaction_rpc(ret < 0);
fdp->pos = ret;
exit_ret:
mutex_unlock(&sql_fs_mutex);
@@ -616,13 +486,12 @@ static int sql_fs_close(int fd)
mutex_lock(&sql_fs_mutex);
- fdp = handle_lookup(&fs_db, fd);
+ fdp = handle_put(&fs_db, fd);
if (!fdp)
goto exit;
- tee_fs_rpc_close(OPTEE_MSG_RPC_CMD_SQL_FS, fd);
- put_fdp(fdp);
-
+ tee_fs_rpc_new_close(OPTEE_MSG_RPC_CMD_SQL_FS, fdp->fd);
+ free(fdp);
ret = 0;
exit:
mutex_unlock(&sql_fs_mutex);
@@ -632,53 +501,57 @@ exit:
static int sql_fs_open(TEE_Result *errno, const char *file, int flags, ...)
{
+ TEE_Result res;
struct sql_fs_fd *fdp = NULL;
- int rflags = flags | TEE_FS_O_RDWR; /* Need to read/write meta */
- int exists;
+ bool created = false;
int fd = -1;
- DMSG("(file: %s, flags: %d)...", file, flags);
-
mutex_lock(&sql_fs_mutex);
*errno = TEE_ERROR_GENERIC;
- exists = !sql_fs_access_rpc(file, TEE_FS_F_OK);
- if (flags & TEE_FS_O_CREATE) {
- if ((flags & TEE_FS_O_EXCL) && exists) {
- *errno = TEE_ERROR_ACCESS_CONFLICT;
- goto exit;
- }
- } else {
- if (!exists) {
- *errno = TEE_ERROR_ITEM_NOT_FOUND;
- goto exit;
- }
- }
-
fdp = (struct sql_fs_fd *)calloc(1, sizeof(*fdp));
if (!fdp) {
*errno = TEE_ERROR_OUT_OF_MEMORY;
goto exit;
}
-
- fdp->fd = tee_fs_rpc_open(OPTEE_MSG_RPC_CMD_SQL_FS, file, rflags);
- if (fdp->fd < 0)
- goto exit;
+ fdp->fd = -1;
fdp->flags = flags;
- fd = read_meta(errno, fdp);
- if (fd < 0)
+ res = read_meta(fdp, file);
+ if (res == TEE_SUCCESS) {
+ if (flags & TEE_FS_O_EXCL) {
+ *errno = TEE_ERROR_ACCESS_CONFLICT;
+ goto exit;
+ }
+ } else if (res == TEE_ERROR_ITEM_NOT_FOUND) {
+ if (!(flags & TEE_FS_O_CREATE)) {
+ *errno = res;
+ goto exit;
+ }
+ res = create_meta(fdp, file);
+ if (res != TEE_SUCCESS) {
+ *errno = res;
+ goto exit;
+ }
+ created = true;
+ } else {
+ *errno = res;
goto exit;
+ }
fd = handle_get(&fs_db, fdp);
exit:
- mutex_unlock(&sql_fs_mutex);
- if (fd < 0)
+ if (fd < 0) {
+ if (fdp && fdp->fd != -1)
+ tee_fs_rpc_new_close(OPTEE_MSG_RPC_CMD_SQL_FS, fdp->fd);
+ if (created)
+ tee_fs_rpc_new_remove(OPTEE_MSG_RPC_CMD_SQL_FS, file);
free(fdp);
- DMSG("...%d", fd);
+ }
+ mutex_unlock(&sql_fs_mutex);
return fd;
}
@@ -772,6 +645,7 @@ exit_ret:
static int sql_fs_write(TEE_Result *errno, int fd, const void *buf, size_t len)
{
+ TEE_Result tee_res;
struct sql_fs_fd *fdp;
size_t remain_bytes = len;
const uint8_t *data_ptr = buf;
@@ -811,7 +685,7 @@ static int sql_fs_write(TEE_Result *errno, int fd, const void *buf, size_t len)
if (fdp->meta.length < (size_t)fdp->pos) {
/* Fill hole */
- res = sql_fs_ftruncate_internal(errno, fd, fdp->pos);
+ res = sql_fs_ftruncate_internal(errno, fdp, fdp->pos);
if (res < 0)
goto exit;
}
@@ -839,7 +713,11 @@ static int sql_fs_write(TEE_Result *errno, int fd, const void *buf, size_t len)
}
fdp->meta.length = fdp->pos;
- res = write_meta(errno, fdp);
+ tee_res = write_meta(fdp);
+ if (tee_res != TEE_SUCCESS) {
+ *errno = tee_res;
+ res = -1;
+ }
exit:
sql_fs_end_transaction_rpc(res < 0);
exit_ret:
@@ -852,9 +730,16 @@ exit_ret:
static int sql_fs_ftruncate(TEE_Result *errno, int fd, tee_fs_off_t new_length)
{
int res;
+ struct sql_fs_fd *fdp;
mutex_lock(&sql_fs_mutex);
- res = sql_fs_ftruncate_internal(errno, fd, new_length);
+ fdp = handle_lookup(&fs_db, fd);
+ if (fdp) {
+ res = sql_fs_ftruncate_internal(errno, fdp, new_length);
+ } else {
+ *errno = TEE_ERROR_GENERIC;
+ res = -1;
+ }
mutex_unlock(&sql_fs_mutex);
return res;