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 4b25a0dfa54560b862c3f117c596dac4ca1eb2e9
Author: liaoao <lia...@xiaomi.com>
AuthorDate: Thu Nov 2 15:19:27 2023 +0800

    rpmsgblk: check if the block device has been removed before calling its ops
    
    it may cause use after free if server has removed block device before 
calling
    its operations,such as:
    server: rm /dev/testrpmsgblk
    client: ls /dev/testrpmsgblk
    
    Signed-off-by: liaoao <lia...@xiaomi.com>
---
 drivers/misc/rpmsgblk_server.c | 50 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/misc/rpmsgblk_server.c b/drivers/misc/rpmsgblk_server.c
index 483f794865..8d1cbe37d3 100644
--- a/drivers/misc/rpmsgblk_server.c
+++ b/drivers/misc/rpmsgblk_server.c
@@ -116,6 +116,16 @@ static int rpmsgblk_open_handler(FAR struct rpmsg_endpoint 
*ept,
   FAR struct rpmsgblk_server_s *server = ept->priv;
   FAR struct rpmsgblk_open_s *msg = data;
 
+  /* To check if the block device has been removed by unlink operation. */
+
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+  if (server->blknode->i_peer == NULL)
+    {
+      msg->header.result = -ENODEV;
+      return rpmsg_send(ept, msg, sizeof(*msg));
+    }
+#endif
+
   if (server->bops->open != NULL)
     {
       msg->header.result = server->bops->open(server->blknode);
@@ -143,6 +153,14 @@ static int rpmsgblk_close_handler(FAR struct 
rpmsg_endpoint *ept,
   FAR struct rpmsgblk_server_s *server = ept->priv;
   FAR struct rpmsgblk_close_s *msg = data;
 
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+  if (server->blknode->i_peer == NULL)
+    {
+      msg->header.result = -ENODEV;
+      return rpmsg_send(ept, msg, sizeof(*msg));
+    }
+#endif
+
   if (server->bops->close != NULL)
     {
       msg->header.result = server->bops->close(server->blknode);
@@ -175,6 +193,14 @@ static int rpmsgblk_read_handler(FAR struct rpmsg_endpoint 
*ept,
   size_t nsectors;
   uint32_t space;
 
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+  if (server->blknode->i_peer == NULL)
+    {
+      msg->header.result = -ENODEV;
+      return rpmsg_send(ept, msg, sizeof(*msg) - 1);
+    }
+#endif
+
   while (read < msg->nsectors)
     {
       rsp = rpmsg_get_tx_payload_buffer(ept, &space, true);
@@ -223,6 +249,14 @@ static int rpmsgblk_write_handler(FAR struct 
rpmsg_endpoint *ept,
   FAR struct rpmsgblk_write_s *msg = data;
   int ret;
 
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+  if (server->blknode->i_peer == NULL)
+    {
+      msg->header.result = -ENODEV;
+      return rpmsg_send(ept, msg, sizeof(*msg) - 1);
+    }
+#endif
+
   ret = server->bops->write(server->blknode, (FAR unsigned char *)msg->buf,
                             msg->startsector, msg->nsectors);
   if (ret <= 0)
@@ -254,6 +288,14 @@ static int rpmsgblk_geometry_handler(FAR struct 
rpmsg_endpoint *ept,
   FAR struct rpmsgblk_server_s *server = ept->priv;
   FAR struct rpmsgblk_geometry_s *msg = data;
 
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+  if (server->blknode->i_peer == NULL)
+    {
+      msg->header.result = -ENODEV;
+      return rpmsg_send(ept, msg, len);
+    }
+#endif
+
   DEBUGASSERT(msg->arglen == sizeof(struct geometry));
 
   msg->header.result = server->bops->geometry(
@@ -273,6 +315,14 @@ static int rpmsgblk_ioctl_handler(FAR struct 
rpmsg_endpoint *ept,
   FAR struct rpmsgblk_server_s *server = ept->priv;
   FAR struct rpmsgblk_ioctl_s *msg = data;
 
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+  if (server->blknode->i_peer == NULL)
+    {
+      msg->header.result = -ENODEV;
+      return rpmsg_send(ept, msg, len);
+    }
+#endif
+
   switch (msg->request)
     {
       case MMC_IOC_CMD:

Reply via email to