die if fd_set overrun. explicitly turn off use of IPv4 mapped addr on AF_INET6

socket.
This commit is contained in:
itojun 2002-08-20 23:02:44 +00:00
parent 1f508ca545
commit 00975d3872
3 changed files with 57 additions and 28 deletions

View File

@ -1,5 +1,5 @@
/* $NetBSD: faithd.c,v 1.26 2002/06/07 00:20:45 itojun Exp $ */ /* $NetBSD: faithd.c,v 1.27 2002/08/20 23:02:44 itojun Exp $ */
/* $KAME: faithd.c,v 1.53 2002/06/07 00:16:37 itojun Exp $ */ /* $KAME: faithd.c,v 1.57 2002/08/20 23:01:00 itojun Exp $ */
/* /*
* Copyright (C) 1997 and 1998 WIDE Project. * Copyright (C) 1997 and 1998 WIDE Project.
@ -216,9 +216,6 @@ daemon_main(int argc, char **argv)
int s_wld, error, i, serverargc, on = 1; int s_wld, error, i, serverargc, on = 1;
int family = AF_INET6; int family = AF_INET6;
int c; int c;
#ifdef FAITH_NS
char *ns;
#endif /* FAITH_NS */
while ((c = getopt(argc, argv, "df:p")) != -1) { while ((c = getopt(argc, argv, "df:p")) != -1) {
switch (c) { switch (c) {
@ -244,23 +241,6 @@ daemon_main(int argc, char **argv)
/*NOTREACHED*/ /*NOTREACHED*/
} }
#ifdef FAITH_NS
if ((ns = getenv(FAITH_NS)) != NULL) {
struct sockaddr_storage ss;
struct addrinfo hints, *res;
char serv[NI_MAXSERV];
memset(&ss, 0, sizeof(ss));
memset(&hints, 0, sizeof(hints));
snprintf(serv, sizeof(serv), "%u", NAMESERVER_PORT);
hints.ai_flags = AI_NUMERICHOST;
if (getaddrinfo(ns, serv, &hints, &res) == 0) {
res_init();
memcpy(&_res_ext.nsaddr, res->ai_addr, res->ai_addrlen);
_res.nscount = 1;
}
}
#endif /* FAITH_NS */
#ifdef USE_ROUTE #ifdef USE_ROUTE
grab_myaddrs(); grab_myaddrs();
@ -328,6 +308,12 @@ daemon_main(int argc, char **argv)
if (error == -1) if (error == -1)
exit_failure("setsockopt(SO_OOBINLINE): %s", strerror(errno)); exit_failure("setsockopt(SO_OOBINLINE): %s", strerror(errno));
#ifdef IPV6_V6ONLY
error = setsockopt(s_wld, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
if (error == -1)
exit_failure("setsockopt(IPV6_V6ONLY): %s", strerror(errno));
#endif
error = bind(s_wld, (struct sockaddr *)res->ai_addr, res->ai_addrlen); error = bind(s_wld, (struct sockaddr *)res->ai_addr, res->ai_addrlen);
if (error == -1) if (error == -1)
exit_failure("bind: %s", strerror(errno)); exit_failure("bind: %s", strerror(errno));
@ -376,10 +362,14 @@ again:
setproctitle("%s", procname); setproctitle("%s", procname);
FD_ZERO(&rfds); FD_ZERO(&rfds);
if (s_wld >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(s_wld, &rfds); FD_SET(s_wld, &rfds);
maxfd = s_wld; maxfd = s_wld;
#ifdef USE_ROUTE #ifdef USE_ROUTE
if (sockfd) { if (sockfd) {
if (sockfd >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(sockfd, &rfds); FD_SET(sockfd, &rfds);
maxfd = (maxfd < sockfd) ? sockfd : maxfd; maxfd = (maxfd < sockfd) ? sockfd : maxfd;
} }
@ -400,14 +390,19 @@ again:
#endif #endif
if (FD_ISSET(s_wld, &rfds)) { if (FD_ISSET(s_wld, &rfds)) {
len = sizeof(srcaddr); len = sizeof(srcaddr);
s_src = accept(s_wld, (struct sockaddr *)&srcaddr, s_src = accept(s_wld, (struct sockaddr *)&srcaddr, &len);
&len);
if (s_src < 0) { if (s_src < 0) {
if (errno == ECONNABORTED) if (errno == ECONNABORTED)
goto again; goto again;
exit_failure("socket: %s", strerror(errno)); exit_failure("socket: %s", strerror(errno));
/*NOTREACHED*/ /*NOTREACHED*/
} }
if (srcaddr.ss_family == AF_INET6 &&
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&srcaddr)->sin6_addr)) {
close(s_src);
syslog(LOG_ERR, "connection from IPv4 mapped address?");
goto again;
}
child_pid = fork(); child_pid = fork();

View File

@ -1,5 +1,5 @@
/* $NetBSD: ftp.c,v 1.10 2002/06/24 06:03:13 itojun Exp $ */ /* $NetBSD: ftp.c,v 1.11 2002/08/20 23:02:44 itojun Exp $ */
/* $KAME: ftp.c,v 1.18 2002/06/23 14:41:47 itojun Exp $ */ /* $KAME: ftp.c,v 1.19 2002/08/20 23:01:01 itojun Exp $ */
/* /*
* Copyright (C) 1997 and 1998 WIDE Project. * Copyright (C) 1997 and 1998 WIDE Project.
@ -83,24 +83,36 @@ ftp_relay(int ctl6, int ctl4)
int maxfd = 0; int maxfd = 0;
FD_ZERO(&readfds); FD_ZERO(&readfds);
if (ctl4 >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(ctl4, &readfds); FD_SET(ctl4, &readfds);
maxfd = ctl4; maxfd = ctl4;
if (ctl6 >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(ctl6, &readfds); FD_SET(ctl6, &readfds);
maxfd = (ctl6 > maxfd) ? ctl6 : maxfd; maxfd = (ctl6 > maxfd) ? ctl6 : maxfd;
if (0 <= port4) { if (0 <= port4) {
if (port4 >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(port4, &readfds); FD_SET(port4, &readfds);
maxfd = (port4 > maxfd) ? port4 : maxfd; maxfd = (port4 > maxfd) ? port4 : maxfd;
} }
if (0 <= port6) { if (0 <= port6) {
if (port6 >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(port6, &readfds); FD_SET(port6, &readfds);
maxfd = (port6 > maxfd) ? port6 : maxfd; maxfd = (port6 > maxfd) ? port6 : maxfd;
} }
#if 0 #if 0
if (0 <= wport4) { if (0 <= wport4) {
if (wport4 >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(wport4, &readfds); FD_SET(wport4, &readfds);
maxfd = (wport4 > maxfd) ? wport4 : maxfd; maxfd = (wport4 > maxfd) ? wport4 : maxfd;
} }
if (0 <= wport6) { if (0 <= wport6) {
if (wport6 >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(wport6, &readfds); FD_SET(wport6, &readfds);
maxfd = (wport6 > maxfd) ? wport6 : maxfd; maxfd = (wport6 > maxfd) ? wport6 : maxfd;
} }
@ -223,6 +235,8 @@ ftp_activeconn()
/* get active connection from server */ /* get active connection from server */
FD_ZERO(&set); FD_ZERO(&set);
if (wport4 >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(wport4, &set); FD_SET(wport4, &set);
timeout.tv_sec = 120; timeout.tv_sec = 120;
timeout.tv_usec = -1; timeout.tv_usec = -1;
@ -270,6 +284,8 @@ ftp_passiveconn()
/* get passive connection from client */ /* get passive connection from client */
FD_ZERO(&set); FD_ZERO(&set);
if (wport6 >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(wport6, &set); FD_SET(wport6, &set);
timeout.tv_sec = 120; timeout.tv_sec = 120;
timeout.tv_usec = 0; timeout.tv_usec = 0;

View File

@ -1,5 +1,5 @@
/* $NetBSD: tcp.c,v 1.8 2002/06/07 00:20:45 itojun Exp $ */ /* $NetBSD: tcp.c,v 1.9 2002/08/20 23:02:45 itojun Exp $ */
/* $KAME: tcp.c,v 1.9 2002/05/26 01:17:02 itojun Exp $ */ /* $KAME: tcp.c,v 1.10 2002/08/20 23:01:01 itojun Exp $ */
/* /*
* Copyright (C) 1997 and 1998 WIDE Project. * Copyright (C) 1997 and 1998 WIDE Project.
@ -156,6 +156,8 @@ send_data(int s_rcv, int s_snd, const char *service, int direction)
if (cc == -1) if (cc == -1)
goto retry_or_err; goto retry_or_err;
oob_exists = 0; oob_exists = 0;
if (s_rcv >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(s_rcv, &exceptfds); FD_SET(s_rcv, &exceptfds);
} }
@ -174,12 +176,18 @@ send_data(int s_rcv, int s_snd, const char *service, int direction)
} }
#endif /* DEBUG */ #endif /* DEBUG */
tblen = 0; tboff = 0; tblen = 0; tboff = 0;
if (s_snd >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_CLR(s_snd, &writefds); FD_CLR(s_snd, &writefds);
if (s_rcv >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(s_rcv, &readfds); FD_SET(s_rcv, &readfds);
return; return;
retry_or_err: retry_or_err:
if (errno != EAGAIN) if (errno != EAGAIN)
exit_failure("writing relay data failed: %s", strerror(errno)); exit_failure("writing relay data failed: %s", strerror(errno));
if (s_snd >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(s_snd, &writefds); FD_SET(s_snd, &writefds);
} }
@ -195,6 +203,8 @@ relay(int s_rcv, int s_snd, const char *service, int direction)
FD_ZERO(&exceptfds); FD_ZERO(&exceptfds);
fcntl(s_snd, F_SETFD, O_NONBLOCK); fcntl(s_snd, F_SETFD, O_NONBLOCK);
oreadfds = readfds; owritefds = writefds; oexceptfds = exceptfds; oreadfds = readfds; owritefds = writefds; oexceptfds = exceptfds;
if (s_rcv >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(s_rcv, &readfds); FD_SET(s_rcv, &readfds);
FD_SET(s_rcv, &exceptfds); FD_SET(s_rcv, &exceptfds);
oob_exists = 0; oob_exists = 0;
@ -229,7 +239,11 @@ relay(int s_rcv, int s_snd, const char *service, int direction)
oob_read_retry: oob_read_retry:
cc = read(s_rcv, atmark_buf, 1); cc = read(s_rcv, atmark_buf, 1);
if (cc == 1) { if (cc == 1) {
if (s_rcv >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_CLR(s_rcv, &exceptfds); FD_CLR(s_rcv, &exceptfds);
if (s_snd >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(s_snd, &writefds); FD_SET(s_snd, &writefds);
oob_exists = 1; oob_exists = 1;
} else if (cc == -1) { } else if (cc == -1) {
@ -262,7 +276,11 @@ relay(int s_rcv, int s_snd, const char *service, int direction)
exit_success("terminating %s relay", service); exit_success("terminating %s relay", service);
/* NOTREACHED */ /* NOTREACHED */
default: default:
if (s_rcv >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_CLR(s_rcv, &readfds); FD_CLR(s_rcv, &readfds);
if (s_snd >= FD_SETSIZE)
exit_failure("descriptor too big");
FD_SET(s_snd, &writefds); FD_SET(s_snd, &writefds);
break; break;
} }