[rtems commit] ftpd: Avoid TOCTOU problem

Sebastian Huber sebh at rtems.org
Fri Nov 2 10:58:54 UTC 2018


Module:    rtems
Branch:    master
Commit:    fa0adf361826e6b79ae408e31ce13ddf82e275fe
Changeset: http://git.rtems.org/rtems/commit/?id=fa0adf361826e6b79ae408e31ce13ddf82e275fe

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Oct 30 11:53:46 2018 +0100

ftpd: Avoid TOCTOU problem

Assume that opendir() returns only non-NULL if we actually open a
directory.

Update #3530.

---

 cpukit/ftpd/ftpd.c | 41 +++++++++++++++--------------------------
 1 file changed, 15 insertions(+), 26 deletions(-)

diff --git a/cpukit/ftpd/ftpd.c b/cpukit/ftpd/ftpd.c
index 8aef440..c4c31c3 100644
--- a/cpukit/ftpd/ftpd.c
+++ b/cpukit/ftpd/ftpd.c
@@ -1245,7 +1245,6 @@ command_list(FTPD_SessionInfo_t *info, char const *fname, bool wide)
   int                 s;
   DIR                 *dirp = 0;
   struct dirent       *dp = 0;
-  struct stat         stat_buf;
   char                buf[FTPD_BUFSIZE];
   time_t curTime;
   bool ok = true;
@@ -1265,39 +1264,29 @@ command_list(FTPD_SessionInfo_t *info, char const *fname, bool wide)
     return;
   }
 
-  if(fname[0] == '\0')
+  if (fname[0] == '\0')
     fname = ".";
 
-  if (0 > stat(fname, &stat_buf))
+  time(&curTime);
+  dirp = opendir(fname);
+  if (dirp != NULL)
   {
-    snprintf(buf, FTPD_BUFSIZE,
-      "%s: No such file or directory.\r\n", fname);
-    send(s, buf, strlen(buf), 0);
-  }
-  else if (S_ISDIR(stat_buf.st_mode) && (NULL == (dirp = opendir(fname))))
-  {
-    snprintf(buf, FTPD_BUFSIZE,
-      "%s: Can not open directory.\r\n", fname);
-    send(s, buf, strlen(buf), 0);
+    /* FIXME: need "." and ".." only when '-a' option is given */
+    ok = ok && send_dirline(s, wide, curTime, fname, "", ".", buf);
+    ok = ok && send_dirline(s, wide, curTime, fname,
+      (strcmp(fname, ftpd_root) ? ".." : ""), "..", buf);
+
+    while (ok && (dp = readdir(dirp)) != NULL)
+      ok = ok &&
+        send_dirline(s, wide, curTime, fname, dp->d_name, dp->d_name, buf);
+
+    closedir(dirp);
   }
   else
   {
-    time(&curTime);
-    if(!dirp && *fname)
-      ok = ok && send_dirline(s, wide, curTime, fname, "", fname, buf);
-    else {
-      /* FIXME: need "." and ".." only when '-a' option is given */
-      ok = ok && send_dirline(s, wide, curTime, fname, "", ".", buf);
-      ok = ok && send_dirline(s, wide, curTime, fname,
-        (strcmp(fname, ftpd_root) ? ".." : ""), "..", buf);
-      while (ok && (dp = readdir(dirp)) != NULL)
-        ok = ok &&
-          send_dirline(s, wide, curTime, fname, dp->d_name, dp->d_name, buf);
-    }
+    send_dirline(s, wide, curTime, fname, "", fname, buf);
   }
 
-  if(dirp)
-    closedir(dirp);
   close_data_socket(info);
 
   if (ok)



More information about the vc mailing list