From: Jarkko Sakkinen <jarkko@kernel.org>
To: David Howells <dhowells@redhat.com>
Cc: Jarkko Sakkinen <jarkko@kernel.org>,
keyrings@vger.kernel.org, linux-afs@lists.infradead.org,
linux-cifs@vger.kernel.org, linux-integrity@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org,
linux-s390@vger.kernel.org,
linux-security-module@vger.kernel.org, netdev@vger.kernel.org,
samba-technical@lists.samba.org,
Alexander Gordeev <agordeev@linux.ibm.com>,
Anna Schumaker <anna@kernel.org>,
Bharath SM <bharathsm@microsoft.com>,
Christian Borntraeger <borntraeger@linux.ibm.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Biggers <ebiggers@kernel.org>,
Eric Dumazet <edumazet@kernel.org>,
Heiko Carstens <hca@linux.ibm.com>,
Jakub Kicinski <kuba@kernel.org>,
James Bottomley <James.Bottomley@HansenPartnership.com>,
James Morris <jmorris@namei.org>,
Marc Dionne <marc.dionne@auristor.com>,
Mimi Zohar <zohar@linux.ibm.com>,
Namjae Jeon <linkinjeon@kernel.org>,
Paolo Abeni <pabeni@redhat.com>, Paul Moore <paul@paul-moore.com>,
Paulo Alcantara <pc@manguebit.org>,
Ronnie Sahlberg <ronniesahlberg@gmail.com>,
"Serge E. Hallyn" <serge@hallyn.com>,
Shyam Prasad N <sprasad@microsoft.com>,
Simon Horman <horms@kernel.org>,
Sumit Garg <sumit.garg@kernel.org>,
Sven Schnelle <svens@linux.ibm.com>, Tom Talpey <tom@talpey.com>,
Trond Myklebust <trondmy@kernel.org>,
Vasily Gorbik <gor@linux.ibm.com>
Subject: [RFC PATCH v3 07/11] KEYS: trusted: TEE: Synchronize session lifetime
Date: Thu, 5 Nov 2026 02:53:06 +0200 [thread overview]
Message-ID: <20261105005311.804098-8-jarkko@kernel.org> (raw)
In-Reply-To: <20261105005311.804098-1-jarkko@kernel.org>
While the sysfs bind attributes are now suppressed, the parent TEE device
can still remove the device while the instances keep trusted.ko loaded.
Update the static calls before invoking backend init() and reset them in
the case of a failure.
In the TEE backend, guard session context state with a mutex, publish
pvt_data.dev before registering key_type_trusted and sanitize pvt_data on
probe failure and removal.
When an active TEE has not been bound, reject seal, unseal and get_random
with -ENODEV.
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
security/keys/trusted-keys/trusted_core.c | 15 ++--
security/keys/trusted-keys/trusted_tee.c | 86 +++++++++++++++++------
2 files changed, 75 insertions(+), 26 deletions(-)
diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
index 0509d9955f2a..11d7d296d063 100644
--- a/security/keys/trusted-keys/trusted_core.c
+++ b/security/keys/trusted-keys/trusted_core.c
@@ -373,14 +373,19 @@ static int __init init_trusted(void)
if (!get_random)
get_random = kernel_get_random;
+ static_call_update(trusted_key_seal, trusted_key_sources[i].ops->seal);
+ static_call_update(trusted_key_unseal, trusted_key_sources[i].ops->unseal);
+ static_call_update(trusted_key_get_random, get_random);
+ migratable = trusted_key_sources[i].ops->migratable;
+
ret = trusted_key_sources[i].ops->init();
if (!ret) {
- static_call_update(trusted_key_seal, trusted_key_sources[i].ops->seal);
- static_call_update(trusted_key_unseal, trusted_key_sources[i].ops->unseal);
- static_call_update(trusted_key_get_random, get_random);
-
trusted_key_exit = trusted_key_sources[i].ops->exit;
- migratable = trusted_key_sources[i].ops->migratable;
+ } else {
+ static_call_update(trusted_key_seal, NULL);
+ static_call_update(trusted_key_unseal, NULL);
+ static_call_update(trusted_key_get_random, NULL);
+ migratable = 0;
}
if (!ret || ret != -ENODEV)
diff --git a/security/keys/trusted-keys/trusted_tee.c b/security/keys/trusted-keys/trusted_tee.c
index 227efb668aa9..87ea549f7f0b 100644
--- a/security/keys/trusted-keys/trusted_tee.c
+++ b/security/keys/trusted-keys/trusted_tee.c
@@ -9,6 +9,7 @@
#include <linux/err.h>
#include <linux/key-type.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/tee_drv.h>
@@ -56,6 +57,8 @@ struct trusted_key_tee_private {
};
static struct trusted_key_tee_private pvt_data;
+/* Do not hold this mutex across key type registration or unregistration. */
+static DEFINE_MUTEX(trusted_key_tee_mutex);
/*
* Have the TEE seal(encrypt) the symmetric key
@@ -67,6 +70,12 @@ static int trusted_tee_seal(struct trusted_key_payload *p, char *datablob)
struct tee_param param[4];
struct tee_shm *reg_shm = NULL;
+ mutex_lock(&trusted_key_tee_mutex);
+ if (!pvt_data.ctx) {
+ ret = -ENODEV;
+ goto out_unlock;
+ }
+
memset(&inv_arg, 0, sizeof(inv_arg));
memset(¶m, 0, sizeof(param));
@@ -74,7 +83,8 @@ static int trusted_tee_seal(struct trusted_key_payload *p, char *datablob)
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);
+ ret = PTR_ERR(reg_shm);
+ goto out_unlock;
}
inv_arg.func = TA_CMD_SEAL;
@@ -100,7 +110,8 @@ static int trusted_tee_seal(struct trusted_key_payload *p, char *datablob)
}
tee_shm_free(reg_shm);
-
+out_unlock:
+ mutex_unlock(&trusted_key_tee_mutex);
return ret;
}
@@ -114,6 +125,12 @@ static int trusted_tee_unseal(struct trusted_key_payload *p, char *datablob)
struct tee_param param[4];
struct tee_shm *reg_shm = NULL;
+ mutex_lock(&trusted_key_tee_mutex);
+ if (!pvt_data.ctx) {
+ ret = -ENODEV;
+ goto out_unlock;
+ }
+
memset(&inv_arg, 0, sizeof(inv_arg));
memset(¶m, 0, sizeof(param));
@@ -121,7 +138,8 @@ static int trusted_tee_unseal(struct trusted_key_payload *p, char *datablob)
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);
+ ret = PTR_ERR(reg_shm);
+ goto out_unlock;
}
inv_arg.func = TA_CMD_UNSEAL;
@@ -147,7 +165,8 @@ static int trusted_tee_unseal(struct trusted_key_payload *p, char *datablob)
}
tee_shm_free(reg_shm);
-
+out_unlock:
+ mutex_unlock(&trusted_key_tee_mutex);
return ret;
}
@@ -161,13 +180,20 @@ static int trusted_tee_get_random(unsigned char *key, size_t key_len)
struct tee_param param[4];
struct tee_shm *reg_shm = NULL;
+ mutex_lock(&trusted_key_tee_mutex);
+ if (!pvt_data.ctx) {
+ ret = -ENODEV;
+ goto out_unlock;
+ }
+
memset(&inv_arg, 0, sizeof(inv_arg));
memset(¶m, 0, sizeof(param));
reg_shm = tee_shm_register_kernel_buf(pvt_data.ctx, key, key_len);
if (IS_ERR(reg_shm)) {
dev_err(pvt_data.dev, "key shm register failed\n");
- return PTR_ERR(reg_shm);
+ ret = PTR_ERR(reg_shm);
+ goto out_unlock;
}
inv_arg.func = TA_CMD_GET_RANDOM;
@@ -189,7 +215,8 @@ static int trusted_tee_get_random(unsigned char *key, size_t key_len)
}
tee_shm_free(reg_shm);
-
+out_unlock:
+ mutex_unlock(&trusted_key_tee_mutex);
return ret;
}
@@ -205,50 +232,67 @@ static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
static int trusted_key_probe(struct tee_client_device *rng_device)
{
struct device *dev = &rng_device->dev;
+ struct tee_context *ctx;
int ret;
struct tee_ioctl_open_session_arg sess_arg;
+ mutex_lock(&trusted_key_tee_mutex);
+ if (pvt_data.ctx) {
+ ret = -EBUSY;
+ goto out_unlock;
+ }
+
memset(&sess_arg, 0, sizeof(sess_arg));
- pvt_data.ctx = tee_client_open_context(NULL, optee_ctx_match, NULL,
- NULL);
- if (IS_ERR(pvt_data.ctx))
- return -ENODEV;
+ ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL);
+ if (IS_ERR(ctx)) {
+ ret = -ENODEV;
+ goto out_unlock;
+ }
memcpy(sess_arg.uuid, rng_device->id.uuid.b, TEE_IOCTL_UUID_LEN);
sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
sess_arg.num_params = 0;
- ret = tee_client_open_session(pvt_data.ctx, &sess_arg, NULL);
+ ret = tee_client_open_session(ctx, &sess_arg, NULL);
if ((ret < 0) || (sess_arg.ret != 0)) {
dev_err(dev, "tee_client_open_session failed, err: %x\n",
sess_arg.ret);
ret = -EINVAL;
goto out_ctx;
}
+ pvt_data.ctx = ctx;
pvt_data.session_id = sess_arg.session;
-
- ret = register_key_type(&key_type_trusted);
- if (ret < 0)
- goto out_sess;
-
pvt_data.dev = dev;
+ mutex_unlock(&trusted_key_tee_mutex);
- return 0;
+ ret = register_key_type(&key_type_trusted);
+ if (!ret)
+ return 0;
-out_sess:
- tee_client_close_session(pvt_data.ctx, pvt_data.session_id);
+ mutex_lock(&trusted_key_tee_mutex);
+ tee_client_close_session(ctx, pvt_data.session_id);
out_ctx:
- tee_client_close_context(pvt_data.ctx);
-
+ tee_client_close_context(ctx);
+ pvt_data.ctx = NULL;
+ pvt_data.dev = NULL;
+ pvt_data.session_id = 0;
+out_unlock:
+ mutex_unlock(&trusted_key_tee_mutex);
return ret;
}
static void trusted_key_remove(struct tee_client_device *dev)
{
unregister_key_type(&key_type_trusted);
+
+ mutex_lock(&trusted_key_tee_mutex);
tee_client_close_session(pvt_data.ctx, pvt_data.session_id);
tee_client_close_context(pvt_data.ctx);
+ pvt_data.ctx = NULL;
+ pvt_data.dev = NULL;
+ pvt_data.session_id = 0;
+ mutex_unlock(&trusted_key_tee_mutex);
}
static const struct tee_client_device_id trusted_key_id_table[] = {
--
2.47.3
next prev parent reply other threads:[~2026-11-05 0:53 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 0:52 [RFC PATCH v3 00/11] KEYS: Sanitize the garbage collector Jarkko Sakkinen
2026-11-05 0:53 ` [RFC PATCH v3 01/11] KEYS: Add key_gc_flush() for draining RCU callbacks Jarkko Sakkinen
2026-11-05 0:53 ` [RFC PATCH v3 02/11] dns_resolver: Move the key type into a separate module Jarkko Sakkinen
2026-11-05 0:53 ` [RFC PATCH v3 03/11] NFSv4: Clear idmap keyring cache when the last client unloads Jarkko Sakkinen
2026-11-05 0:53 ` [RFC PATCH v3 04/11] smb: client: Clear idmap/SPNEGO caches when the last session is unloaded Jarkko Sakkinen
2026-11-05 0:53 ` [RFC PATCH v3 05/11] s390/cert_store: Start tracking subsystem keys Jarkko Sakkinen
2026-11-05 0:53 ` [RFC PATCH v3 06/11] KEYS: trusted: TEE: Disable sysfs bind attributes Jarkko Sakkinen
2026-11-05 0:53 ` Jarkko Sakkinen [this message]
2026-11-05 0:53 ` [RFC PATCH v3 08/11] rxrpc: Move key types to their own module Jarkko Sakkinen
2026-11-05 0:53 ` [RFC PATCH v3 09/11] KEYS: Pin the backing kernel module for a key type Jarkko Sakkinen
2026-11-05 0:53 ` [RFC PATCH v3 10/11] KEYS: Remove key_type_dead Jarkko Sakkinen
2026-11-05 0:53 ` [RFC PATCH v3 11/11] KEYS: key_garbage_collector(): process in chunks Jarkko Sakkinen
2026-11-05 1:04 ` [RFC PATCH v3 00/11] KEYS: Sanitize the garbage collector Jarkko Sakkinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261105005311.804098-8-jarkko@kernel.org \
--to=jarkko@kernel.org \
--cc=James.Bottomley@HansenPartnership.com \
--cc=agordeev@linux.ibm.com \
--cc=anna@kernel.org \
--cc=bharathsm@microsoft.com \
--cc=borntraeger@linux.ibm.com \
--cc=davem@davemloft.net \
--cc=dhowells@redhat.com \
--cc=ebiggers@kernel.org \
--cc=edumazet@kernel.org \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=horms@kernel.org \
--cc=jmorris@namei.org \
--cc=keyrings@vger.kernel.org \
--cc=kuba@kernel.org \
--cc=linkinjeon@kernel.org \
--cc=linux-afs@lists.infradead.org \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=marc.dionne@auristor.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=paul@paul-moore.com \
--cc=pc@manguebit.org \
--cc=ronniesahlberg@gmail.com \
--cc=samba-technical@lists.samba.org \
--cc=serge@hallyn.com \
--cc=sprasad@microsoft.com \
--cc=sumit.garg@kernel.org \
--cc=svens@linux.ibm.com \
--cc=tom@talpey.com \
--cc=trondmy@kernel.org \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox