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 6f77cb6dce35272f07a6e7a2c2716c000c41789f
Author: George Poulios <gpoul...@census-labs.com>
AuthorDate: Sat May 10 17:46:59 2025 +0300

    drivers/misc/optee: Proper cleanup of registered shm
    
    This is mostly to handle the case that the user calls
    close() before calling close() on the shm. In that case
    optee_close() frees the shm and then optee_shm_close()
    operates on an invalid reference. Fix that.
    
    Signed-off-by: George Poulios <gpoul...@census-labs.com>
---
 drivers/misc/optee.c | 24 +++++++++++++++++++++---
 drivers/misc/optee.h |  1 +
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/optee.c b/drivers/misc/optee.c
index 05ec397022..427de42262 100644
--- a/drivers/misc/optee.c
+++ b/drivers/misc/optee.c
@@ -476,8 +476,13 @@ static int optee_shm_close(FAR struct file *filep)
 {
   FAR struct optee_shm *shm = filep->f_priv;
 
-  optee_shm_free(shm);
-  filep->f_priv = NULL;
+  if (shm != NULL && shm->id > -1)
+    {
+      filep->f_priv = NULL;
+      shm->fd = -1;
+      optee_shm_free(shm);
+    }
+
   return 0;
 }
 
@@ -529,10 +534,21 @@ static int optee_close(FAR struct file *filep)
 {
   FAR struct optee_priv_data *priv = filep->f_priv;
   FAR struct optee_shm *shm;
+  FAR struct file *shm_filep;
   int id = 0;
 
   idr_for_each_entry(priv->shms, shm, id)
     {
+      if (shm->fd > -1 && fs_getfilep(shm->fd, &shm_filep) >= 0)
+        {
+          /* The user did not call close(), prevent vfs auto-close from
+           * double-freeing our SHM
+           */
+
+          shm_filep->f_priv = NULL;
+          fs_putfilep(shm_filep);
+        }
+
       optee_shm_free(shm);
     }
 
@@ -1009,6 +1025,7 @@ optee_ioctl_shm_register(FAR struct optee_priv_data *priv,
       return ret;
     }
 
+  shm->fd = ret;
   rdata->id = shm->id;
   return ret;
 }
@@ -1169,6 +1186,7 @@ int optee_shm_alloc(FAR struct optee_priv_data *priv, FAR 
void *addr,
       goto err;
     }
 
+  shm->fd = -1;
   shm->priv = priv;
   shm->addr = (uintptr_t)ptr;
   shm->length = size;
@@ -1221,7 +1239,7 @@ err:
 
 void optee_shm_free(FAR struct optee_shm *shm)
 {
-  if (!shm)
+  if (!shm || !shm->priv)
     {
       return;
     }
diff --git a/drivers/misc/optee.h b/drivers/misc/optee.h
index 108dec218e..27feb16664 100644
--- a/drivers/misc/optee.h
+++ b/drivers/misc/optee.h
@@ -54,6 +54,7 @@ struct optee_priv_data
 struct optee_shm
 {
   FAR struct optee_priv_data *priv;
+  int fd;
   int32_t id;
   uint64_t addr;
   uint64_t length;

Reply via email to