be more paranoid about UDP-based echo services validation. namely,

reject the following sources:
	0.0.0.0/8 127.0.0.0/8 240.0.0.0/4 255.0.0.0/8
	ff00::/8 ::/128
	::ffff:0.0.0.0/96 and ::0.0.0.0/96 obeys IPv4 rule.
hint from deraadt.
This commit is contained in:
itojun 2000-08-01 18:42:08 +00:00
parent 058e85bfc6
commit 51156effd6
1 changed files with 37 additions and 18 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: inetd.c,v 1.70 2000/07/23 22:54:51 mycroft Exp $ */
/* $NetBSD: inetd.c,v 1.71 2000/08/01 18:42:08 itojun Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -77,7 +77,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1991, 1993, 1994\n\
#if 0
static char sccsid[] = "@(#)inetd.c 8.4 (Berkeley) 4/13/94";
#else
__RCSID("$NetBSD: inetd.c,v 1.70 2000/07/23 22:54:51 mycroft Exp $");
__RCSID("$NetBSD: inetd.c,v 1.71 2000/08/01 18:42:08 itojun Exp $");
#endif
#endif /* not lint */
@ -2448,7 +2448,7 @@ int ctrl;
#endif
/*
* check if the port where send data to is one of the obvious ports
* check if the address/port where send data to is one of the obvious ports
* that are used for denial of service attacks like two echo ports
* just echoing data between them
*/
@ -2456,6 +2456,10 @@ int
port_good_dg(sa)
struct sockaddr *sa;
{
struct in_addr in;
#ifdef INET6
struct in6_addr *in6;
#endif
u_int16_t port;
int i, bad;
char hbuf[NI_MAXHOST];
@ -2464,11 +2468,28 @@ port_good_dg(sa)
switch (sa->sa_family) {
case AF_INET:
in.s_addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
port = ntohs(((struct sockaddr_in *)sa)->sin_port);
v4chk:
if (IN_MULTICAST(in.s_addr))
goto bad;
switch ((in.s_addr & 0xff000000) >> 24) {
case 0: case 127: case 255:
goto bad;
}
/* XXX check for subnet broadcast using getifaddrs(3) */
break;
#ifdef INET6
case AF_INET6:
in6 = &((struct sockaddr_in6 *)sa)->sin6_addr;
port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
if (IN6_IS_ADDR_MULTICAST(in6) || IN6_IS_ADDR_UNSPECIFIED(in6))
goto bad;
if (IN6_IS_ADDR_V4MAPPED(in6) || IN6_IS_ADDR_V4COMPAT(in6)) {
memcpy(&in, &in6->s6_addr[12], sizeof(in));
in.s_addr = ntohl(in.s_addr);
goto v4chk;
}
break;
#endif
default:
@ -2476,20 +2497,18 @@ port_good_dg(sa)
return 1;
}
for (i = 0; bad_ports[i] != 0; i++)
if (port == bad_ports[i]) {
bad = 1;
break;
}
for (i = 0; bad_ports[i] != 0; i++) {
if (port == bad_ports[i])
goto bad;
}
if (bad) {
if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf),
NULL, 0, niflags) != 0)
strcpy(hbuf, "?");
syslog(LOG_WARNING,"Possible DoS attack from %s, Port %d",
hbuf, port);
return (0);
} else
return (1);
return (1);
bad:
if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf),
NULL, 0, niflags) != 0)
strcpy(hbuf, "?");
syslog(LOG_WARNING,"Possible DoS attack from %s, Port %d",
hbuf, port);
return (0);
}