liamHowatt opened a new pull request, #17821:
URL: https://github.com/apache/nuttx/pull/17821

   ```
   Fix a race on userfs_state_s iobuffer.
   
   1. Task 1 takes the mutex and does a userfs operation.
   2. A higher priority task 2 blocks on the mutex.
   3. Task 1 releases the mutex when finished. The iobuffer response has not
      been processed by task 1 yet, but task 2 is higher priority
      and control switches to it.
   4. Task 2 does a userfs operation and releases the mutex.
      The iobuffer now contains task 2's response.
   5. Control returns to task 1 for it to check the iobuffer
      response. It contains task 2's response, not its own.
   
   Fix it by releasing the mutex only after the exclusive iobuffer
   usage lifecycle is complete.
   ```
   
   *Note: Please adhere to [Contributing 
Guidelines](https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md).*
   
   ## Summary
   
   Fix a race on buffer. As the message above describes, there is contention 
over a buffer from multiple tasks accessing a userfs. It can manifest as the 
error message `userfs_rename: ERROR: Incorrect response: 19`. See below.
   
   Should it be fixed with `goto` instead?
   
   ## Impact
   
   No impact.
   
   ## Testing
   
   `sim:userfs` defconfig with `CONFIG_DEBUG_FS_ERROR` to get the "Incorrect 
response" error message.  Full defconfig at the bottom. Use modified hello or 
other app to demonstrate the issue.
   
   For the demonstration, make the example userfs rename operation take some 
time.
   
   ```diff
   diff --git a/examples/userfs/userfs_main.c b/examples/userfs/userfs_main.c
   index a2cf97ea5..6ad469a3b 100644
   --- a/examples/userfs/userfs_main.c
   +++ b/examples/userfs/userfs_main.c
   @@ -519,6 +519,7 @@ static int ufstest_rmdir(FAR void *volinfo, FAR const 
char *relpath)
    static int ufstest_rename(FAR void *volinfo, FAR const char *oldrelpath,
                              FAR const char *newrelpath)
    {
   +  sleep(2);
      FAR struct ufstest_file_s *file;
    
      file = ufstest_findbyname(oldrelpath);
   ```
   
   "Hello" program that demonstrates the race.
   
   ```c
   #include <nuttx/config.h>
   #include <stdio.h>
   #include <unistd.h>
   #include <sys/types.h>
   #include <sys/stat.h>
   #include <sched.h>
   
   static int high_prio_stat(int argc, char *argv[])
   {
     int res;
     struct stat statbuf;
   
     /* wait for `main` to enter `rename` */
     sleep(1);
   
     /* will block waiting for mutex held by `rename` */
     res = stat("/mnt/ufstest/File1", &statbuf);
     if (res < 0)
       {
         return 1;
       }
   
     return 0;
   }
   
   int main(int argc, FAR char *argv[])
   {
     FAR char *nshargv[1];
     int pid;
     int res;
   
     nshargv[0] = NULL;
     pid = task_create("high_prio_stat", 120,
                       2048, high_prio_stat,
                       (FAR char * const *)nshargv);
     if (pid < 0)
       {
         return 1;
       }
   
     /* take the mutex and block in userfs_main.c for 2 seconds */
     res = rename("/mnt/ufstest/File3", "/mnt/ufstest/foobar");
     if (res < 0)
       {
         return 1;
       }
   
     return 0;
   }
   ```
   
   It produces this result:
   
   ```
   nsh> userfs
   nsh> hello
   userfs_rename: ERROR: Incorrect response: 19
   nsh>
   ```
   
   Full defconfig:
   
   ```
   #
   # This file is autogenerated: PLEASE DO NOT EDIT IT.
   #
   # You can use "make menuconfig" to make any modifications to the installed 
.config file.
   # You can then do "make savedefconfig" to generate a new defconfig file that 
includes your
   # modifications.
   #
   # CONFIG_DEBUG_INFO is not set
   # CONFIG_NET_ETHERNET is not set
   # CONFIG_NSH_CMDOPT_HEXDUMP is not set
   # CONFIG_NSH_NETINIT is not set
   CONFIG_ARCH="sim"
   CONFIG_ARCH_BOARD="sim"
   CONFIG_ARCH_BOARD_SIM=y
   CONFIG_ARCH_CHIP="sim"
   CONFIG_ARCH_SIM=y
   CONFIG_BOARDCTL_POWEROFF=y
   CONFIG_BOARD_LOOPSPERMSEC=0
   CONFIG_BOOT_RUNFROMEXTSRAM=y
   CONFIG_BUILTIN=y
   CONFIG_CCACHE=y
   CONFIG_DEBUG_ASSERTIONS=y
   CONFIG_DEBUG_FEATURES=y
   CONFIG_DEBUG_FS=y
   CONFIG_DEBUG_FS_ERROR=y
   CONFIG_DEBUG_FS_WARN=y
   CONFIG_DEBUG_SYMBOLS=y
   CONFIG_DEV_LOOP=y
   CONFIG_ETC_FATDEVNO=2
   CONFIG_ETC_ROMFS=y
   CONFIG_ETC_ROMFSDEVNO=1
   CONFIG_EXAMPLES_HELLO=y
   CONFIG_EXAMPLES_USERFS=y
   CONFIG_FAT_LCNAMES=y
   CONFIG_FAT_LFN=y
   CONFIG_FRAME_POINTER=y
   CONFIG_FSUTILS_PASSWD=y
   CONFIG_FSUTILS_PASSWD_READONLY=y
   CONFIG_FS_FAT=y
   CONFIG_FS_PROCFS=y
   CONFIG_FS_ROMFS=y
   CONFIG_FS_USERFS=y
   CONFIG_IDLETHREAD_STACKSIZE=4096
   CONFIG_INIT_ENTRYPOINT="nsh_main"
   CONFIG_LIBC_ENVPATH=y
   CONFIG_LIBC_EXECFUNCS=y
   CONFIG_LIBC_MAX_EXITFUNS=1
   CONFIG_MM_CUSTOMIZE_MANAGER=y
   CONFIG_NET=y
   CONFIG_NET_LOCAL=y
   CONFIG_NET_LOOPBACK=y
   CONFIG_NET_UDP=y
   CONFIG_NSH_ARCHINIT=y
   CONFIG_NSH_BUILTIN_APPS=y
   CONFIG_NSH_FILE_APPS=y
   CONFIG_NSH_READLINE=y
   CONFIG_PATH_INITIAL="/bin"
   CONFIG_READLINE_TABCOMPLETION=y
   CONFIG_SCHED_HAVE_PARENT=y
   CONFIG_SCHED_LPWORK=y
   CONFIG_SCHED_WAITPID=y
   CONFIG_SIM_ASAN=y
   CONFIG_START_MONTH=6
   CONFIG_START_YEAR=2008
   CONFIG_SYSTEM_NSH=y
   ```
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to