summaryrefslogtreecommitdiffstats
path: root/libexec/ftpd
diff options
context:
space:
mode:
authorcjc <cjc@FreeBSD.org>2003-01-21 05:13:02 +0000
committercjc <cjc@FreeBSD.org>2003-01-21 05:13:02 +0000
commit29a813efb6672f6dfe60ef33e869adbd662cf866 (patch)
treeb18f9ebde4f2e8b1174dc86dae83fb4552b3e4ac /libexec/ftpd
parent9d5889a3d98b3a2e7b8c3f82bf7630c443e23054 (diff)
downloadFreeBSD-src-29a813efb6672f6dfe60ef33e869adbd662cf866.zip
FreeBSD-src-29a813efb6672f6dfe60ef33e869adbd662cf866.tar.gz
The FTP daemon was vulnerable to a DoS where an attacker could bind()
up port 20 for an extended period of time and thus lock out all other users from establishing PORT data connections. Don't hold on to the bind() while we loop around waiting to see if we can make our connection. Being a DoS, it has security implications, giving it a short MFC time. MFC after: 1 day
Diffstat (limited to 'libexec/ftpd')
-rw-r--r--libexec/ftpd/ftpd.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c
index 1f5ce00..d59edd6 100644
--- a/libexec/ftpd/ftpd.c
+++ b/libexec/ftpd/ftpd.c
@@ -1772,7 +1772,7 @@ dataconn(char *name, off_t size, char *mode)
{
char sizebuf[32];
FILE *file;
- int retry = 0, tos;
+ int retry = 0, tos, conerrno;
file_size = size;
byte_count = 0;
@@ -1840,28 +1840,35 @@ pdata_err:
if (usedefault)
data_dest = his_addr;
usedefault = 1;
- file = getdatasock(mode);
- if (file == NULL) {
- char hostbuf[BUFSIZ], portbuf[BUFSIZ];
- getnameinfo((struct sockaddr *)&data_source,
- data_source.su_len, hostbuf, sizeof(hostbuf) - 1,
- portbuf, sizeof(portbuf),
- NI_NUMERICHOST|NI_NUMERICSERV);
- reply(425, "Can't create data socket (%s,%s): %s.",
- hostbuf, portbuf, strerror(errno));
- return (NULL);
- }
- data = fileno(file);
- while (connect(data, (struct sockaddr *)&data_dest,
- data_dest.su_len) < 0) {
- if (errno == EADDRINUSE && retry < swaitmax) {
+ do {
+ file = getdatasock(mode);
+ if (file == NULL) {
+ char hostbuf[BUFSIZ], portbuf[BUFSIZ];
+ getnameinfo((struct sockaddr *)&data_source,
+ data_source.su_len, hostbuf, sizeof(hostbuf) - 1,
+ portbuf, sizeof(portbuf),
+ NI_NUMERICHOST|NI_NUMERICSERV);
+ reply(425, "Can't create data socket (%s,%s): %s.",
+ hostbuf, portbuf, strerror(errno));
+ return (NULL);
+ }
+ data = fileno(file);
+ conerrno = 0;
+ if (connect(data, (struct sockaddr *)&data_dest,
+ data_dest.su_len) == 0)
+ break;
+ conerrno = errno;
+ (void) fclose(file);
+ data = -1;
+ if (conerrno == EADDRINUSE) {
sleep((unsigned) swaitint);
retry += swaitint;
- continue;
+ } else {
+ break;
}
+ } while (retry <= swaitmax);
+ if (conerrno != 0) {
perror_reply(425, "Can't build data connection");
- (void) fclose(file);
- data = -1;
return (NULL);
}
reply(150, "Opening %s mode data connection for '%s'%s.",
OpenPOWER on IntegriCloud