Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 Feb 2001 21:49:00 +0100 (CET)
From:      Jesper Skriver <jesper@skriver.dk>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/25195: security update to sys/netinet/in_pcb.c:in_pcbnotify
Message-ID:  <200102182049.f1IKn0B00683@tam.skriver.dk>

next in thread | raw e-mail | index | archive | help

>Number:         25195
>Category:       kern
>Synopsis:       a attacker can make ICMP messages apply to all sessions.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Feb 18 12:50:01 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Jesper Skriver
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
>Environment:
System: FreeBSD tam 5.0-CURRENT FreeBSD 5.0-CURRENT #2: Sun Feb 18 21:15:41 CET 2001 root@tam:/usr/obj/usr/src/sys/TAM2 i386


	
>Description:
	In the current code we take the port numbers and address from the ICMP packet
we get in, and we use 0 as a wildcard indicator - this means if a attacker sends
us a ICMP packet where the attached IP header (+ 8 bytes) has the address and port
numbers == 0, then we'll treat it as a wildcard, and apply the notification to
all sessions.

>How-To-Repeat:
	
>Fix:

	Apply this fix.

diff -ru sys/netinet.old/in_pcb.c sys/netinet/in_pcb.c
--- sys/netinet.old/in_pcb.c	Sun Feb 18 19:28:38 2001
+++ sys/netinet/in_pcb.c	Sun Feb 18 21:03:13 2001
@@ -671,7 +671,8 @@
  * a valid TCP sequence number for the session.
  */
 void
-in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify, tcp_sequence, tcp_seq_check)
+in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify, tcp_sequence,
+		tcp_seq_check, wild_match)
 	struct inpcbhead *head;
 	struct sockaddr *dst;
 	u_int fport_arg, lport_arg;
@@ -680,6 +681,7 @@
 	void (*notify) __P((struct inpcb *, int));
 	u_int32_t tcp_sequence;
 	int tcp_seq_check;
+	int wild_match;
 {
 	register struct inpcb *inp, *oinp;
 	struct in_addr faddr;
@@ -700,9 +702,7 @@
 	 * deliver only to that socket.
 	 */
 	if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) {
-		fport = 0;
-		lport = 0;
-		laddr.s_addr = 0;
+		wild_match = IN_PCBNOTIFY_WILDCARD;
 		if (cmd != PRC_HOSTDEAD)
 			notify = in_rtchange;
 	}
@@ -715,11 +715,10 @@
 			continue;
 		}
 #endif
-		if (inp->inp_faddr.s_addr != faddr.s_addr ||
-		    inp->inp_socket == 0 ||
-		    (lport && inp->inp_lport != lport) ||
-		    (laddr.s_addr && inp->inp_laddr.s_addr != laddr.s_addr) ||
-		    (fport && inp->inp_fport != fport)) {
+		if (inp->inp_faddr.s_addr != faddr.s_addr || inp->inp_socket == 0 ||
+			(wild_match == IN_PCBNOTIFY_NOT_WILDCARD &&
+			(inp->inp_lport != lport || inp->inp_laddr.s_addr != laddr.s_addr ||
+		    inp->inp_fport != fport))) {
 			inp = LIST_NEXT(inp, inp_list);
 			continue;
 		}
@@ -733,7 +732,6 @@
 		 * and TCP port numbers.
 		 */
 		if ((tcp_seq_check == 1) && (tcp_seq_vs_sess(inp, tcp_sequence) == 0)) {
-			inp = LIST_NEXT(inp, inp_list);
 			break;
 		}
 		oinp = inp;
diff -ru sys/netinet.old/in_pcb.h sys/netinet/in_pcb.h
--- sys/netinet.old/in_pcb.h	Sun Feb 18 19:28:38 2001
+++ sys/netinet/in_pcb.h	Sun Feb 18 20:42:57 2001
@@ -291,7 +291,9 @@
 			       int, struct ifnet *));
 void	in_pcbnotify __P((struct inpcbhead *, struct sockaddr *,
 	    u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int),
-		u_int32_t, int));
+		u_int32_t, int, int));
+#define	IN_PCBNOTIFY_NOT_WILDCARD	0
+#define	IN_PCBNOTIFY_WILDCARD	1
 void	in_pcbrehash __P((struct inpcb *));
 int	in_setpeeraddr __P((struct socket *so, struct sockaddr **nam));
 int	in_setsockaddr __P((struct socket *so, struct sockaddr **nam));
diff -ru sys/netinet.old/tcp_subr.c sys/netinet/tcp_subr.c
--- sys/netinet.old/tcp_subr.c	Sun Feb 18 19:28:38 2001
+++ sys/netinet/tcp_subr.c	Sun Feb 18 20:46:58 2001
@@ -1033,9 +1033,11 @@
 		if (tcp_seq_check == 1)
 			tcp_sequence = ntohl(th->th_seq);
 		in_pcbnotify(&tcb, sa, th->th_dport, ip->ip_src, th->th_sport,
-			cmd, notify, tcp_sequence, tcp_seq_check);
+			cmd, notify, tcp_sequence, tcp_seq_check,
+			IN_PCBNOTIFY_NOT_WILDCARD);
 	} else
-		in_pcbnotify(&tcb, sa, 0, zeroin_addr, 0, cmd, notify, 0, 0);
+		in_pcbnotify(&tcb, sa, 0, zeroin_addr, 0, cmd, notify, 0,
+			0, IN_PCBNOTIFY_WILDCARD);
 }
 
 #ifdef INET6
diff -ru sys/netinet.old/udp_usrreq.c sys/netinet/udp_usrreq.c
--- sys/netinet.old/udp_usrreq.c	Sun Feb 18 19:28:38 2001
+++ sys/netinet/udp_usrreq.c	Sun Feb 18 20:46:05 2001
@@ -512,9 +512,10 @@
 	if (ip) {
 		uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
 		in_pcbnotify(&udb, sa, uh->uh_dport, ip->ip_src, uh->uh_sport,
-			cmd, udp_notify, 0, 0);
+			cmd, udp_notify, 0, 0, IN_PCBNOTIFY_NOT_WILDCARD);
 	} else
-		in_pcbnotify(&udb, sa, 0, zeroin_addr, 0, cmd, udp_notify, 0, 0);
+		in_pcbnotify(&udb, sa, 0, zeroin_addr, 0, cmd, udp_notify, 0,
+			0, IN_PCBNOTIFY_WILDCARD);
 }
 
 static int

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200102182049.f1IKn0B00683>