The "dirp" pointer is not closed if goto inside the while loop is called.
This diff: - closes the dirp object - moves the jump mark "out" a bit higher to clean the file pointer as well as the descriptor if the goto statement is called, and reset global variables The "send_file_list" function is only called on NLST. --F. Index: ftpd.c =================================================================== RCS file: /cvs/src/libexec/ftpd/ftpd.c,v retrieving revision 1.213 diff -u -r1.213 ftpd.c --- ftpd.c 16 Mar 2016 15:41:10 -0000 1.213 +++ ftpd.c 29 Mar 2016 19:44:21 -0000 @@ -2704,6 +2704,7 @@ myoob(); recvurg = 0; transflag = 0; + (void)closedir(dirp); goto out; } @@ -2725,8 +2726,10 @@ if (dout == NULL) { dout = dataconn("file list", (off_t)-1, "w"); - if (dout == NULL) + if (dout == NULL) { + (void)closedir(dirp); goto out; + } transflag++; } if (nbuf[0] == '.' && nbuf[1] == '/') @@ -2738,7 +2741,7 @@ byte_count += strlen(nbuf) + 1; } } - (void) closedir(dirp); + (void)closedir(dirp); } if (dout == NULL) @@ -2748,16 +2751,17 @@ else reply(226, "Transfer complete."); +out: transflag = 0; if (dout != NULL) - (void) fclose(dout); + (void)fclose(dout); else { if (pdata >= 0) close(pdata); } data = -1; pdata = -1; -out: + if (freeglob) { freeglob = 0; globfree(&gl);