From: zhenwei pi <zhenwei.pi@linux.dev>
To: Gonglei <arei.gonglei@huawei.com>,
qemu-devel@nongnu.org, berrange@redhat.com,
qemu-security@nongnu.org
Cc: mcascell@redhat.com, Buzzy <buzzy0257@gmail.com>
Subject: Re: [PATCH v2] backends/cryptodev-lkcf: fix use-after-free in session lifecycle
Date: Thu, 16 Apr 2026 14:25:45 +0800 [thread overview]
Message-ID: <6128bece-0ce1-4e46-a4c6-9208dd211ee9@linux.dev> (raw)
In-Reply-To: <20260416061933.1982-1-arei.gonglei@huawei.com>
Reviewed-by: zhenwei pi <zhenwei.pi@linux.dev>
On 4/16/26 14:19, Gonglei wrote:
> The cryptodev-lkcf backend had a race condition where session close
> could free a session while tasks using that session were still pending
> in the queue. This leads to use-after-free when the worker thread
> later accesses the freed session pointer.
>
> Add reference counting (in_use) and pending_close flag to ensure:
> - New operations are rejected when a session is closing
> - Session close waits for all in-flight tasks to complete
> - No use-after-free can occur
>
> Fixes: CVE-2026-6288
> Fixes: 39fff6f3e8 ("cryptodev: Add a lkcf-backend for cryptodev")
> Reported-by: Buzzy <buzzy0257@gmail.com>
> Signed-off-by: Gonglei <arei.gonglei@huawei.com>
> Tested-by: Buzzy <buzzy0257@gmail.com>
> ---
> Changes:
>
> v2:
> * moved sess->pending_close checking before @task allocated
> in cryptodev_lkcf_operation().
>
> ---
> backends/cryptodev-lkcf.c | 59 ++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 58 insertions(+), 1 deletion(-)
>
> diff --git a/backends/cryptodev-lkcf.c b/backends/cryptodev-lkcf.c
> index 40c7bd3c5a..3a93c81372 100644
> --- a/backends/cryptodev-lkcf.c
> +++ b/backends/cryptodev-lkcf.c
> @@ -66,6 +66,9 @@ typedef struct CryptoDevBackendLKCFSession {
> size_t keylen;
> QCryptoAkCipherKeyType keytype;
> QCryptoAkCipherOptions akcipher_opts;
> + int in_use; /* number of tasks currently using this session */
> + /* session close requested, waiting for in_use to become 0 */
> + bool pending_close;
> } CryptoDevBackendLKCFSession;
>
> typedef struct CryptoDevLKCFTask CryptoDevLKCFTask;
> @@ -428,6 +431,18 @@ out:
> if (key_id >= 0) {
> keyctl_unlink(key_id, KCTL_KEY_RING);
> }
> +
> + /*
> + * Decrement session in_use counter and signal if session is pending close.
> + * This allows close_session to proceed after all tasks complete.
> + */
> + qemu_mutex_lock(&task->lkcf->mutex);
> + task->sess->in_use--;
> + if (task->sess->pending_close && task->sess->in_use == 0) {
> + qemu_cond_broadcast(&task->lkcf->cond);
> + }
> + qemu_mutex_unlock(&task->lkcf->mutex);
> +
> task->status = status;
>
> qemu_mutex_lock(&task->lkcf->rsp_mutex);
> @@ -486,12 +501,32 @@ static int cryptodev_lkcf_operation(
> return -VIRTIO_CRYPTO_INVSESS;
> }
>
> - sess = lkcf->sess[op_info->session_id];
> if (algtype != QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM) {
> error_report("algtype not supported: %u", algtype);
> return -VIRTIO_CRYPTO_NOTSUPP;
> }
>
> + /*
> + * Check if session is pending close and increment in_use counter
> + * atomically under the mutex. This prevents the session from being
> + * freed while a task is pending.
> + */
> + qemu_mutex_lock(&lkcf->mutex);
> + sess = lkcf->sess[op_info->session_id];
> + if (!sess) {
> + qemu_mutex_unlock(&lkcf->mutex);
> + error_report("Cannot find a valid session id: %" PRIu64 "",
> + op_info->session_id);
> + return -VIRTIO_CRYPTO_INVSESS;
> + }
> + if (sess->pending_close) {
> + qemu_mutex_unlock(&lkcf->mutex);
> + error_report("Session %" PRIu64 " is closing", op_info->session_id);
> + return -VIRTIO_CRYPTO_INVSESS;
> + }
> + sess->in_use++;
> + qemu_mutex_unlock(&lkcf->mutex);
> +
> task = g_new0(CryptoDevLKCFTask, 1);
> task->op_info = op_info;
> task->cb = op_info->cb;
> @@ -606,8 +641,30 @@ static int cryptodev_lkcf_close_session(CryptoDevBackend *backend,
> CryptoDevBackendLKCFSession *session;
>
> assert(session_id < MAX_SESSIONS && lkcf->sess[session_id]);
> +
> + qemu_mutex_lock(&lkcf->mutex);
> session = lkcf->sess[session_id];
> +
> + /*
> + * Mark session as pending close. New operations using this session
> + * will be rejected. We hold the mutex until in_use becomes 0 to
> + * prevent race conditions.
> + */
> + session->pending_close = true;
> +
> + /*
> + * Wait for all in-flight tasks using this session to complete.
> + * The worker thread decrements in_use after task execution.
> + */
> + while (session->in_use > 0) {
> + qemu_cond_wait(&lkcf->cond, &lkcf->mutex);
> + }
> +
> + /*
> + * Now safe to remove session and free resources.
> + */
> lkcf->sess[session_id] = NULL;
> + qemu_mutex_unlock(&lkcf->mutex);
>
> g_free(session->key);
> g_free(session);
next prev parent reply other threads:[~2026-04-16 6:27 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-16 6:19 [PATCH v2] backends/cryptodev-lkcf: fix use-after-free in session lifecycle Gonglei
2026-04-16 6:25 ` zhenwei pi [this message]
2026-05-11 10:48 ` Daniel P. Berrangé
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=6128bece-0ce1-4e46-a4c6-9208dd211ee9@linux.dev \
--to=zhenwei.pi@linux.dev \
--cc=arei.gonglei@huawei.com \
--cc=berrange@redhat.com \
--cc=buzzy0257@gmail.com \
--cc=mcascell@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-security@nongnu.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.