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

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

commit 3b3e97e4a8050a7fd5a6d46a479f89139e94ca25
Author: Xiang Xiao <[email protected]>
AuthorDate: Fri Sep 11 02:23:15 2026 +0800

    fs/aio: add internal aio_read/aio_write to avoid lio_link overwrite
    
    lio_listio() links each aiocbp->lio_link into its batch list before
    submitting the I/O, but submitted the operations through the public
    aio_read()/aio_write(), which re-initialized lio_link and destroyed
    the list membership.  With an aiocb pre-filled with garbage (as in
    ostest), the completion path then walked an invalid list.
    
    Extract aio_read_internal()/aio_write_internal() that skip the
    lio_link setup; aio_read()/aio_write() initialize lio_link (and
    reject a NULL aiocbp) before calling the internal functions, while
    lio_listio() calls the internal functions directly to preserve its
    own lio_link setup.  For entries that are not part of a batch,
    lio_listio() self-initializes lio_link instead.
    
    Signed-off-by: Xiang Xiao <[email protected]>
---
 fs/aio/aio.h        |  3 +++
 fs/aio/aio_read.c   | 14 +++++++++++++-
 fs/aio/aio_write.c  | 14 +++++++++++++-
 fs/aio/lio_listio.c | 17 ++++++++++++-----
 4 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/fs/aio/aio.h b/fs/aio/aio.h
index dbe0b2fbb90..b0caf9e0cf8 100644
--- a/fs/aio/aio.h
+++ b/fs/aio/aio.h
@@ -239,6 +239,9 @@ int aio_queue(FAR struct aio_container_s *aioc, worker_t 
worker);
 
 int aio_signal(pid_t pid, FAR struct aiocb *aiocbp);
 
+int aio_read_internal(FAR struct aiocb *aiocbp);
+int aio_write_internal(FAR struct aiocb *aiocbp);
+
 #undef EXTERN
 #if defined(__cplusplus)
 }
diff --git a/fs/aio/aio_read.c b/fs/aio/aio_read.c
index 670784d4301..dc092d42727 100644
--- a/fs/aio/aio_read.c
+++ b/fs/aio/aio_read.c
@@ -215,7 +215,7 @@ static void aio_read_worker(FAR void *arg)
  *
  ****************************************************************************/
 
-int aio_read(FAR struct aiocb *aiocbp)
+int aio_read_internal(FAR struct aiocb *aiocbp)
 {
   FAR struct aio_container_s *aioc;
   int ret;
@@ -267,4 +267,16 @@ int aio_read(FAR struct aiocb *aiocbp)
   return OK;
 }
 
+int aio_read(FAR struct aiocb *aiocbp)
+{
+  if (aiocbp == NULL)
+    {
+      set_errno(EINVAL);
+      return ERROR;
+    }
+
+  list_initialize(&aiocbp->lio_link);
+  return aio_read_internal(aiocbp);
+}
+
 #endif /* CONFIG_FS_AIO */
diff --git a/fs/aio/aio_write.c b/fs/aio/aio_write.c
index 7c2b425a125..f0fea80373d 100644
--- a/fs/aio/aio_write.c
+++ b/fs/aio/aio_write.c
@@ -245,7 +245,7 @@ errout:
  *
  ****************************************************************************/
 
-int aio_write(FAR struct aiocb *aiocbp)
+int aio_write_internal(FAR struct aiocb *aiocbp)
 {
   FAR struct aio_container_s *aioc;
   int ret;
@@ -303,4 +303,16 @@ int aio_write(FAR struct aiocb *aiocbp)
   return OK;
 }
 
+int aio_write(FAR struct aiocb *aiocbp)
+{
+  if (aiocbp == NULL)
+    {
+      set_errno(EINVAL);
+      return ERROR;
+    }
+
+  list_initialize(&aiocbp->lio_link);
+  return aio_write_internal(aiocbp);
+}
+
 #endif /* CONFIG_FS_AIO */
diff --git a/fs/aio/lio_listio.c b/fs/aio/lio_listio.c
index 196677529d4..59847ba9319 100644
--- a/fs/aio/lio_listio.c
+++ b/fs/aio/lio_listio.c
@@ -349,15 +349,22 @@ int lio_listio(int mode, FAR struct aiocb *restrict const 
list[restrict],
   if (mode == LIO_NOWAIT && sig)
     {
       list_initialize(&head);
+    }
 
-      for (i = 0; i < nent; i++)
+  for (i = 0; i < nent; i++)
+    {
+      aiocbp = list[i];
+      if (aiocbp && aiocbp->aio_lio_opcode != LIO_NOP)
         {
-          aiocbp = list[i];
-          if (aiocbp && aiocbp->aio_lio_opcode != LIO_NOP)
+          if (mode == LIO_NOWAIT && sig)
             {
               list_add_head(&head, &(aiocbp->lio_link));
               aiocbp->lio_sigevent = *sig;
             }
+          else
+            {
+              list_initialize(&aiocbp->lio_link);
+            }
         }
     }
 
@@ -392,13 +399,13 @@ int lio_listio(int mode, FAR struct aiocb *restrict const 
list[restrict],
                   {
                     /* Submit the asynchronous read operation */
 
-                    status = aio_read(aiocbp);
+                    status = aio_read_internal(aiocbp);
                   }
                 else
                   {
                     /* Submit the asynchronous write operation */
 
-                    status = aio_write(aiocbp);
+                    status = aio_write_internal(aiocbp);
                   }
 
                 if (status < 0)

Reply via email to