forked from Imagelibrary/rtems
ftpd: Avoid TOCTOU problem
Assume that opendir() returns only non-NULL if we actually open a directory. Update #3530.
This commit is contained in:
@@ -1245,7 +1245,6 @@ command_list(FTPD_SessionInfo_t *info, char const *fname, bool wide)
|
|||||||
int s;
|
int s;
|
||||||
DIR *dirp = 0;
|
DIR *dirp = 0;
|
||||||
struct dirent *dp = 0;
|
struct dirent *dp = 0;
|
||||||
struct stat stat_buf;
|
|
||||||
char buf[FTPD_BUFSIZE];
|
char buf[FTPD_BUFSIZE];
|
||||||
time_t curTime;
|
time_t curTime;
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
@@ -1265,39 +1264,29 @@ command_list(FTPD_SessionInfo_t *info, char const *fname, bool wide)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fname[0] == '\0')
|
if (fname[0] == '\0')
|
||||||
fname = ".";
|
fname = ".";
|
||||||
|
|
||||||
if (0 > stat(fname, &stat_buf))
|
time(&curTime);
|
||||||
|
dirp = opendir(fname);
|
||||||
|
if (dirp != NULL)
|
||||||
{
|
{
|
||||||
snprintf(buf, FTPD_BUFSIZE,
|
/* FIXME: need "." and ".." only when '-a' option is given */
|
||||||
"%s: No such file or directory.\r\n", fname);
|
ok = ok && send_dirline(s, wide, curTime, fname, "", ".", buf);
|
||||||
send(s, buf, strlen(buf), 0);
|
ok = ok && send_dirline(s, wide, curTime, fname,
|
||||||
}
|
(strcmp(fname, ftpd_root) ? ".." : ""), "..", buf);
|
||||||
else if (S_ISDIR(stat_buf.st_mode) && (NULL == (dirp = opendir(fname))))
|
|
||||||
{
|
while (ok && (dp = readdir(dirp)) != NULL)
|
||||||
snprintf(buf, FTPD_BUFSIZE,
|
ok = ok &&
|
||||||
"%s: Can not open directory.\r\n", fname);
|
send_dirline(s, wide, curTime, fname, dp->d_name, dp->d_name, buf);
|
||||||
send(s, buf, strlen(buf), 0);
|
|
||||||
|
closedir(dirp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
time(&curTime);
|
send_dirline(s, wide, curTime, fname, "", fname, buf);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dirp)
|
|
||||||
closedir(dirp);
|
|
||||||
close_data_socket(info);
|
close_data_socket(info);
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
|
|||||||
Reference in New Issue
Block a user