Changeset 706802f8 in rtems


Ignore:
Timestamp:
Oct 30, 2018, 8:35:06 AM (6 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
8c3cd1e8
Parents:
7e2aabd7
git-author:
Sebastian Huber <sebastian.huber@…> (10/30/18 08:35:06)
git-committer:
Sebastian Huber <sebastian.huber@…> (10/30/18 12:27:03)
Message:

ftpd: Make send_dirline() more robust

Account for large file names.

Update #3530.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/ftpd/ftpd.c

    r7e2aabd7 r706802f8  
    11331133 *
    11341134 * Output parameters:
    1135  *   returns 0 on failure, 1 on success
    1136  *
    1137  */
    1138 static int
    1139 send_dirline(int s, int wide, time_t curTime, char const* path,
     1135 *   returns false on failure, true on success
     1136 *
     1137 */
     1138static bool
     1139send_dirline(int s, bool wide, time_t curTime, char const* path,
    11401140  char const* add, char const* fname, char* buf)
    11411141{
    1142   if(wide)
    1143   {
    1144     struct stat stat_buf;
    1145 
    1146     int plen = strlen(path);
    1147     int alen = strlen(add);
    1148     if(plen == 0)
     1142  struct stat stat_buf;
     1143  size_t plen = strlen(path);
     1144  size_t alen = strlen(add);
     1145  int slen = 0;
     1146
     1147  if(plen == 0)
     1148  {
     1149    buf[plen++] = '/';
     1150    buf[plen] = '\0';
     1151  }
     1152  else
     1153  {
     1154    buf = memcpy(buf, path, plen + 1);
     1155    if(alen > 0 && buf[plen - 1] != '/')
    11491156    {
    11501157      buf[plen++] = '/';
     1158      if(plen >= FTPD_BUFSIZE)
     1159        return 0;
    11511160      buf[plen] = '\0';
    11521161    }
    1153     else
    1154     {
    1155       strcpy(buf, path);
    1156       if(alen > 0 && buf[plen - 1] != '/')
    1157       {
    1158         buf[plen++] = '/';
    1159         if(plen >= FTPD_BUFSIZE)
    1160           return 0;
    1161         buf[plen] = '\0';
    1162       }
    1163     }
    1164     if(plen + alen >= FTPD_BUFSIZE)
    1165       return 0;
    1166     strcpy(buf + plen, add);
    1167 
    1168     if (stat(buf, &stat_buf) == 0)
    1169     {
    1170       int len;
     1162  }
     1163  if(plen + alen >= FTPD_BUFSIZE)
     1164    return 0;
     1165  memcpy(buf + plen, add, alen + 1);
     1166
     1167  if (stat(buf, &stat_buf) == 0)
     1168  {
     1169    if (wide)
     1170    {
    11711171      struct tm bt;
    11721172      time_t tf = stat_buf.st_mtime;
     
    11801180        strftime (timeBuf, SIZE, "%b %d %H:%M", &bt);
    11811181
    1182       len = snprintf(buf, FTPD_BUFSIZE,
     1182      slen = snprintf(buf, FTPD_BUFSIZE,
    11831183        "%c%c%c%c%c%c%c%c%c%c  1 %5d %5d %11u %s %s\r\n",
    11841184        (S_ISLNK(stat_buf.st_mode)?('l'):
     
    11991199        fname
    12001200      );
    1201 
    1202       if(send(s, buf, len, 0) != len)
    1203         return 0;
     1201    }
     1202    else
     1203    {
     1204      slen = snprintf(buf, FTPD_BUFSIZE, "%s\r\n", fname);
    12041205    }
    12051206  }
    12061207  else
    12071208  {
    1208     int len = snprintf(buf, FTPD_BUFSIZE, "%s\r\n", fname);
    1209     if(send(s, buf, len, 0) != len)
    1210       return 0;
    1211   }
    1212   return 1;
     1209    slen = snprintf(buf, FTPD_BUFSIZE, "%s: %s.\r\n", fname, strerror(errno));
     1210  }
     1211
     1212  if (slen >= FTPD_BUFSIZE)
     1213  {
     1214    static const char dots[] = { '.', '.', '.', '\r', '\n' };
     1215
     1216    /*
     1217     * The file name exceeds the send buffer, indicate this with a ... at the
     1218     * end of the line.
     1219     */
     1220    slen = FTPD_BUFSIZE - 1;
     1221    memcpy(&buf[slen - sizeof(dots)], dots, sizeof(dots));
     1222  }
     1223
     1224  if (slen > 0 && send(s, buf, (size_t) slen, 0) != slen)
     1225    return false;
     1226
     1227  return true;
    12131228}
    12141229
     
    12261241 */
    12271242static void
    1228 command_list(FTPD_SessionInfo_t *info, char const *fname, int wide)
     1243command_list(FTPD_SessionInfo_t *info, char const *fname, bool wide)
    12291244{
    12301245  int                 s;
     
    12341249  char                buf[FTPD_BUFSIZE];
    12351250  time_t curTime;
    1236   int sc = 1;
     1251  bool ok = true;
    12371252
    12381253  if(!info->auth)
     
    12701285    time(&curTime);
    12711286    if(!dirp && *fname)
    1272       sc = sc && send_dirline(s, wide, curTime, fname, "", fname, buf);
     1287      ok = ok && send_dirline(s, wide, curTime, fname, "", fname, buf);
    12731288    else {
    12741289      /* FIXME: need "." and ".." only when '-a' option is given */
    1275       sc = sc && send_dirline(s, wide, curTime, fname, "", ".", buf);
    1276       sc = sc && send_dirline(s, wide, curTime, fname,
     1290      ok = ok && send_dirline(s, wide, curTime, fname, "", ".", buf);
     1291      ok = ok && send_dirline(s, wide, curTime, fname,
    12771292        (strcmp(fname, ftpd_root) ? ".." : ""), "..", buf);
    1278       while (sc && (dp = readdir(dirp)) != NULL)
    1279         sc = sc &&
     1293      while (ok && (dp = readdir(dirp)) != NULL)
     1294        ok = ok &&
    12801295          send_dirline(s, wide, curTime, fname, dp->d_name, dp->d_name, buf);
    12811296    }
     
    12861301  close_data_socket(info);
    12871302
    1288   if(sc)
     1303  if (ok)
    12891304    send_reply(info, 226, "Transfer complete.");
    12901305  else
     
    16951710  else if (!strcmp("LIST", cmd))
    16961711  {
    1697     command_list(info, args, 1);
     1712    command_list(info, args, true);
    16981713  }
    16991714  else if (!strcmp("NLST", cmd))
    17001715  {
    1701     command_list(info, args, 0);
     1716    command_list(info, args, false);
    17021717  }
    17031718  else if (!strcmp("MDTM", cmd))
Note: See TracChangeset for help on using the changeset viewer.