You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2021/05/20 17:58:20 UTC

[GitHub] [incubator-nuttx] patacongo commented on issue #3751: nucleo-h743zi:elf config got broken (nsh: nsh_session: readline failed: 13)

patacongo commented on issue #3751:
URL: https://github.com/apache/incubator-nuttx/issues/3751#issuecomment-845343585


   > [468e08c](https://github.com/apache/incubator-nuttx/commit/468e08c1b4ff1441cf898623782869c7daf1c947) is the first bad commit
   > [e5f1069](https://github.com/apache/incubator-nuttx/commit/e5f10696541dcbd53337b90f53538a48d073b4bc) is the last good commit
   
   When I first looked, 468e08c seemed like an unlikely cause of the problem.  That commit simply changes some error handling if the ELF load fails.  The ELF loader simply calls `elf_uninit()` in the event of a failure:
   
       65 int elf_uninit(struct elf_loadinfo_s *loadinfo)
       66 {
       67   /* Free all working buffers */
       68
       69   elf_freebuffers(loadinfo);
       70
       71   /* Close the ELF file */
       72
       73   if (loadinfo->filfd >= 0)
       74     {
       75       nx_close(loadinfo->filfd);
       76     }
       77
       78   return OK;
       79 }
   
   You see a failure that is attributed to readline() which seems unrelated:
   
       79 #define EACCES              13
       80 #define EACCES_STR          "Permission denied"
   
   The error is reported, apparently, by logic in `apps/nshlib/nsh_stdsession.c` if a call to `readline()` returns EOF.  `readline()` ultimately calls `read()` on stdin (file descriptor 0).  `EACCES` is returned from `read()` if the file is not opened for reading:
   
       71   /* Was this file opened for read access? */
       72
       73   if ((filep->f_oflags & O_RDOK) == 0)
       74     {
       75       /* No.. File is not read-able */
       76
       77       ret = -EACCES;
       78     }
       79
   
   So now I think I see how this commit can cause this error to be seen:
   
   1. When ELF support is enabled, NSH will always first attempt to a program with that command name at the PATH directory.  For example, `nsh> ls` will attempt to run at `/bin/ls`
   2. In this case it will fail to run the problem and will fail silently.  It will call `elf_unit()` which will close the file at descriptor `loadinfo->filfd`.  But that file descriptor has not been initialized and is still at its initial state; of zero:
   
       elf_init():
       136   memset(loadinfo, 0, sizeof(struct elf_loadinfo_s));
   
   3. So `stdin` will be closed (via close -> nx_close -> file_close).
   4. After this fails, then readline() is called which will attempt to `read()` from `stdin`. But `read()` will fail will errno `EACCES` because stdin is no open for writing.
   
   
   


-- 
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org