This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 3b151ae44bb88e5841f703083f4cb6371eec0ff5
Author: makejian <[email protected]>
AuthorDate: Wed Jul 30 11:36:23 2025 +0800

    crypto/cryptodev: fix async callback
    
    Fix incorrect memory management for asynchronous process callbacks.
    
    Ensure callback memory is self-managed to prevent leaks or use-after-free 
issues.
    
    Signed-off-by: makejian <[email protected]>
---
 crypto/cryptodev.c         | 45 +++++++++++++++++++++++++++------------------
 include/crypto/cryptodev.h |  2 ++
 2 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/crypto/cryptodev.c b/crypto/cryptodev.c
index 23e8414a052..d8c10dd0f4e 100644
--- a/crypto/cryptodev.c
+++ b/crypto/cryptodev.c
@@ -501,6 +501,7 @@ static int cryptodev_op(FAR struct csession *cse,
 
 static int cryptodev_key(FAR struct fcrypt *fcr, FAR struct crypt_kop *kop)
 {
+  FAR struct cryptkop *krp_async = NULL;
   FAR struct cryptkop *krp = NULL;
   int error = -EINVAL;
   int in;
@@ -686,8 +687,20 @@ static int cryptodev_key(FAR struct fcrypt *fcr, FAR 
struct crypt_kop *kop)
   krp->krp_status = 0;
   krp->krp_flags = kop->crk_flags;
   krp->krp_reqid = kop->crk_reqid;
-  krp->krp_fcr = fcr;
-  krp->krp_callback = cryptodevkey_cb;
+
+  if (krp->krp_flags & CRYPTO_F_CBIMM)
+    {
+      if (kop->crk_arg == NULL)
+        {
+          error = -EINVAL;
+          goto fail;
+        }
+
+      krp_async = (FAR struct cryptkop *)kop->crk_arg;
+      krp_async->krp_fcr = fcr;
+      krp_async->krp_callback = cryptodevkey_cb;
+      krp->krp_opaque = krp_async;
+    }
 
   for (i = 0; i < CRK_MAXPARAM; i++)
     {
@@ -783,11 +796,20 @@ static int cryptodev_getkeystatus(struct fcrypt *fcr, 
struct crypt_kop *ret)
       return -EAGAIN;
     }
 
-  /* return the result in task list to the upper layer  */
+  TAILQ_FOREACH(krp, &fcr->crpk_ret, krp_next)
+    {
+      if (krp->krp_reqid == ret->crk_reqid)
+        {
+          break;
+        }
+    }
 
-  krp = TAILQ_FIRST(&fcr->crpk_ret);
-  TAILQ_REMOVE(&fcr->crpk_ret, krp, krp_next);
+  if (krp == NULL)
+    {
+      return -EINVAL;
+    }
 
+  TAILQ_REMOVE(&fcr->crpk_ret, krp, krp_next);
   ret->crk_op = krp->krp_op;
   ret->crk_status = krp->krp_status;
   ret->crk_iparams = krp->krp_iparams;
@@ -806,19 +828,6 @@ static int cryptodev_getkeystatus(struct fcrypt *fcr, 
struct crypt_kop *ret)
       memcpy(ret->crk_param[i].crp_p, krp->krp_param[i].crp_p, size);
     }
 
-  /* free asynchronous result */
-
-  for (i = 0; i < CRK_MAXPARAM; i++)
-    {
-      if (krp->krp_param[i].crp_p)
-        {
-          explicit_bzero(krp->krp_param[i].crp_p,
-              (krp->krp_param[i].crp_nbits + 7) / 8);
-          kmm_free(krp->krp_param[i].crp_p);
-        }
-    }
-
-  kmm_free(krp);
   return OK;
 }
 
diff --git a/include/crypto/cryptodev.h b/include/crypto/cryptodev.h
index fa8240bfb86..969b9202e51 100644
--- a/include/crypto/cryptodev.h
+++ b/include/crypto/cryptodev.h
@@ -262,6 +262,7 @@ struct crypt_kop
   u_int crk_flags;
   struct crparam crk_param[CRK_MAXPARAM];
   uint32_t crk_reqid;
+  FAR void *crk_arg;   /* callback parameter */
 };
 
 #define CRK_MOD_EXP                0
@@ -333,6 +334,7 @@ struct cryptkop
   FAR struct fcrypt *krp_fcr;
   u_int krp_flags;     /* same as cryptop */
   uint32_t krp_reqid;  /* distinguish tasks in asynchronous calling */
+  FAR void *krp_opaque;
 };
 
 /* Crypto capabilities structure */

Reply via email to