summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorSumit Garg <sumit.garg@linaro.org>2023-08-22 14:29:33 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-11-28 20:07:10 +0300
commit454ad98f31f0d16571c7e2158c279cbe954f7e80 (patch)
tree8b1fb210d5f5f9b8dc779a60c11ddf4bcea7dc69 /security
parent3ef9944681eb576da27615e907dd2f88f14b88e1 (diff)
downloadlinux-454ad98f31f0d16571c7e2158c279cbe954f7e80.tar.xz
KEYS: trusted: tee: Refactor register SHM usage
commit c745cd1718b7825d69315fe7127e2e289e617598 upstream. The OP-TEE driver using the old SMC based ABI permits overlapping shared buffers, but with the new FF-A based ABI each physical page may only be registered once. As the key and blob buffer are allocated adjancently, there is no need for redundant register shared memory invocation. Also, it is incompatibile with FF-A based ABI limitation. So refactor register shared memory implementation to use only single invocation to register both key and blob buffers. [jarkko: Added cc to stable.] Cc: stable@vger.kernel.org # v5.16+ Fixes: 4615e5a34b95 ("optee: add FF-A support") Reported-by: Jens Wiklander <jens.wiklander@linaro.org> Signed-off-by: Sumit Garg <sumit.garg@linaro.org> Tested-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'security')
-rw-r--r--security/keys/trusted-keys/trusted_tee.c64
1 files changed, 20 insertions, 44 deletions
diff --git a/security/keys/trusted-keys/trusted_tee.c b/security/keys/trusted-keys/trusted_tee.c
index c8626686ee1b..24f67ca8d713 100644
--- a/security/keys/trusted-keys/trusted_tee.c
+++ b/security/keys/trusted-keys/trusted_tee.c
@@ -65,24 +65,16 @@ static int trusted_tee_seal(struct trusted_key_payload *p, char *datablob)
int ret;
struct tee_ioctl_invoke_arg inv_arg;
struct tee_param param[4];
- struct tee_shm *reg_shm_in = NULL, *reg_shm_out = NULL;
+ struct tee_shm *reg_shm = NULL;
memset(&inv_arg, 0, sizeof(inv_arg));
memset(&param, 0, sizeof(param));
- reg_shm_in = tee_shm_register_kernel_buf(pvt_data.ctx, p->key,
- p->key_len);
- if (IS_ERR(reg_shm_in)) {
- dev_err(pvt_data.dev, "key shm register failed\n");
- return PTR_ERR(reg_shm_in);
- }
-
- reg_shm_out = tee_shm_register_kernel_buf(pvt_data.ctx, p->blob,
- sizeof(p->blob));
- if (IS_ERR(reg_shm_out)) {
- dev_err(pvt_data.dev, "blob shm register failed\n");
- ret = PTR_ERR(reg_shm_out);
- goto out;
+ reg_shm = tee_shm_register_kernel_buf(pvt_data.ctx, p->key,
+ sizeof(p->key) + sizeof(p->blob));
+ if (IS_ERR(reg_shm)) {
+ dev_err(pvt_data.dev, "shm register failed\n");
+ return PTR_ERR(reg_shm);
}
inv_arg.func = TA_CMD_SEAL;
@@ -90,13 +82,13 @@ static int trusted_tee_seal(struct trusted_key_payload *p, char *datablob)
inv_arg.num_params = 4;
param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
- param[0].u.memref.shm = reg_shm_in;
+ param[0].u.memref.shm = reg_shm;
param[0].u.memref.size = p->key_len;
param[0].u.memref.shm_offs = 0;
param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
- param[1].u.memref.shm = reg_shm_out;
+ param[1].u.memref.shm = reg_shm;
param[1].u.memref.size = sizeof(p->blob);
- param[1].u.memref.shm_offs = 0;
+ param[1].u.memref.shm_offs = sizeof(p->key);
ret = tee_client_invoke_func(pvt_data.ctx, &inv_arg, param);
if ((ret < 0) || (inv_arg.ret != 0)) {
@@ -107,11 +99,7 @@ static int trusted_tee_seal(struct trusted_key_payload *p, char *datablob)
p->blob_len = param[1].u.memref.size;
}
-out:
- if (reg_shm_out)
- tee_shm_free(reg_shm_out);
- if (reg_shm_in)
- tee_shm_free(reg_shm_in);
+ tee_shm_free(reg_shm);
return ret;
}
@@ -124,24 +112,16 @@ static int trusted_tee_unseal(struct trusted_key_payload *p, char *datablob)
int ret;
struct tee_ioctl_invoke_arg inv_arg;
struct tee_param param[4];
- struct tee_shm *reg_shm_in = NULL, *reg_shm_out = NULL;
+ struct tee_shm *reg_shm = NULL;
memset(&inv_arg, 0, sizeof(inv_arg));
memset(&param, 0, sizeof(param));
- reg_shm_in = tee_shm_register_kernel_buf(pvt_data.ctx, p->blob,
- p->blob_len);
- if (IS_ERR(reg_shm_in)) {
- dev_err(pvt_data.dev, "blob shm register failed\n");
- return PTR_ERR(reg_shm_in);
- }
-
- reg_shm_out = tee_shm_register_kernel_buf(pvt_data.ctx, p->key,
- sizeof(p->key));
- if (IS_ERR(reg_shm_out)) {
- dev_err(pvt_data.dev, "key shm register failed\n");
- ret = PTR_ERR(reg_shm_out);
- goto out;
+ reg_shm = tee_shm_register_kernel_buf(pvt_data.ctx, p->key,
+ sizeof(p->key) + sizeof(p->blob));
+ if (IS_ERR(reg_shm)) {
+ dev_err(pvt_data.dev, "shm register failed\n");
+ return PTR_ERR(reg_shm);
}
inv_arg.func = TA_CMD_UNSEAL;
@@ -149,11 +129,11 @@ static int trusted_tee_unseal(struct trusted_key_payload *p, char *datablob)
inv_arg.num_params = 4;
param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
- param[0].u.memref.shm = reg_shm_in;
+ param[0].u.memref.shm = reg_shm;
param[0].u.memref.size = p->blob_len;
- param[0].u.memref.shm_offs = 0;
+ param[0].u.memref.shm_offs = sizeof(p->key);
param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
- param[1].u.memref.shm = reg_shm_out;
+ param[1].u.memref.shm = reg_shm;
param[1].u.memref.size = sizeof(p->key);
param[1].u.memref.shm_offs = 0;
@@ -166,11 +146,7 @@ static int trusted_tee_unseal(struct trusted_key_payload *p, char *datablob)
p->key_len = param[1].u.memref.size;
}
-out:
- if (reg_shm_out)
- tee_shm_free(reg_shm_out);
- if (reg_shm_in)
- tee_shm_free(reg_shm_in);
+ tee_shm_free(reg_shm);
return ret;
}