Date: Sun, 17 Dec 2000 23:41:19 +0100 From: Jesper Skriver <jesper@skriver.dk> To: freebsd-net@FreeBSD.org, cvs-all@FreeBSD.org Cc: Kris Kennaway <kris@FreeBSD.ORG>, Poul-Henning Kamp <phk@FreeBSD.ORG>, cvs-committers@FreeBSD.ORG, security-officer@FreeBSD.ORG, "Louis A. Mamakos" <louie@TransSys.COM> Subject: Re: cvs commit: src/sys/netinet ip_icmp.c tcp_subr.c tcp_var.h Message-ID: <20001217234119.A90024@skriver.dk> In-Reply-To: <20001217200425.D34282@skriver.dk>; from jesper@skriver.dk on Sun, Dec 17, 2000 at 08:04:25PM %2B0100 References: <200012161942.eBGJg7j93654@freefall.freebsd.org> <20001217012007.A18038@citusc.usc.edu> <200012171529.eBHFT4512582@whizzo.transsys.com> <20001217182056.B34282@skriver.dk> <20001217183016.C34282@skriver.dk> <20001217200425.D34282@skriver.dk>
next in thread | previous in thread | raw e-mail | index | archive | help
--4Ckj6UjgE2iN1+kY Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sun, Dec 17, 2000 at 08:04:25PM +0100, Jesper Skriver wrote: > The only thing I can see, we can do to improve the security of this, > would be to match agaist the TCP sequence number too, I have a patch for > this too, but I need to test it, will be back. Attached is a diff which implement this, it's very strict and require that the sequence number we get is == the last unacknowledged packet we sent, thus only working with one unacknowledged packet. Later (probably tomorrow) I'll look at ways of getting it to work with multiple outstanding packets. But somone probably wants to commit the attached, as it's significant better than what's currently in the tree. /Jesper -- Jesper Skriver, jesper(at)skriver(dot)dk - CCIE #5456 Work: Network manager @ AS3292 (Tele Danmark DataNetworks) Private: Geek @ AS2109 (A much smaller network ;-) One Unix to rule them all, One Resolver to find them, One IP to bring them all and in the zone to bind them. --4Ckj6UjgE2iN1+kY Content-Type: text/plain; charset=us-ascii Content-Description: tcp_drop_icmp_unreach.diff Content-Disposition: attachment; filename="tcp_drop_icmp_unreach.diff" diff -ru sys/netinet.old/in_pcb.c sys/netinet/in_pcb.c --- sys/netinet.old/in_pcb.c Sun Dec 17 18:57:24 2000 +++ sys/netinet/in_pcb.c Sun Dec 17 23:32:45 2000 @@ -62,6 +62,8 @@ #include <netinet/in_pcb.h> #include <netinet/in_var.h> #include <netinet/ip_var.h> +#include <netinet/tcp.h> +#include <netinet/tcp_var.h> #ifdef INET6 #include <netinet/ip6.h> #include <netinet6/ip6_var.h> @@ -667,13 +669,14 @@ * any errors for each matching socket. */ void -in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify) +in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify, tcp_sequence) struct inpcbhead *head; struct sockaddr *dst; u_int fport_arg, lport_arg; struct in_addr laddr; int cmd; void (*notify) __P((struct inpcb *, int)); + u_int32_t tcp_sequence; { register struct inpcb *inp, *oinp; struct in_addr faddr; @@ -716,6 +719,17 @@ (fport && inp->inp_fport != fport)) { inp = inp->inp_list.le_next; continue; + } + /* + * If tcp_sequence is set, then only match sessions + * where last packet sent had this sequence number. + */ + if (tcp_sequence) { + struct tcpcb *tp = intotcpcb(inp); + if (tp->snd_una != tcp_sequence) { + inp = inp->inp_list.le_next; + continue; + } } oinp = inp; inp = inp->inp_list.le_next; diff -ru sys/netinet.old/in_pcb.h sys/netinet/in_pcb.h --- sys/netinet.old/in_pcb.h Sun Dec 17 18:57:24 2000 +++ sys/netinet/in_pcb.h Sun Dec 17 22:47:39 2000 @@ -290,7 +290,7 @@ struct in_addr, u_int, struct in_addr, u_int, int, struct ifnet *)); void in_pcbnotify __P((struct inpcbhead *, struct sockaddr *, - u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int))); + u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int), u_int32_t)); 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 Dec 17 18:57:24 2000 +++ sys/netinet/tcp_subr.c Sun Dec 17 23:21:07 2000 @@ -139,7 +139,7 @@ * as required by rfc1122 section 3.2.2.1 */ -static int icmp_admin_prohib_like_rst = 0; +static int icmp_admin_prohib_like_rst = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_admin_prohib_like_rst, CTLFLAG_RW, &icmp_admin_prohib_like_rst, 0, "Treat ICMP administratively prohibited messages like TCP RST, rfc1122 section 3.2.2.1"); @@ -967,11 +967,12 @@ register struct ip *ip = vip; register struct tcphdr *th; void (*notify) __P((struct inpcb *, int)) = tcp_notify; + tcp_seq tcp_sequence = 0; if (cmd == PRC_QUENCH) notify = tcp_quench; else if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT) && (ip)) - notify = tcp_drop_syn_sent; + notify = tcp_drop_icmp_unreach; else if (cmd == PRC_MSGSIZE) notify = tcp_mtudisc; else if (!PRC_IS_REDIRECT(cmd) && @@ -980,10 +981,12 @@ if (ip) { th = (struct tcphdr *)((caddr_t)ip + (IP_VHL_HL(ip->ip_vhl) << 2)); + if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT)) + tcp_sequence = ntohl(th->th_seq); in_pcbnotify(&tcb, sa, th->th_dport, ip->ip_src, th->th_sport, - cmd, notify); + cmd, notify, tcp_sequence); } else - in_pcbnotify(&tcb, sa, 0, zeroin_addr, 0, cmd, notify); + in_pcbnotify(&tcb, sa, 0, zeroin_addr, 0, cmd, notify, 0); } #ifdef INET6 @@ -1086,16 +1089,16 @@ /* * When a ICMP unreachable is recieved, drop the - * TCP connection, but only if in SYN_SENT + * TCP connection */ void -tcp_drop_syn_sent(inp, errno) +tcp_drop_icmp_unreach(inp, errno) struct inpcb *inp; int errno; { struct tcpcb *tp = intotcpcb(inp); - if((tp) && (tp->t_state == TCPS_SYN_SENT)) - tcp_drop(tp, errno); + if(tp) + tcp_drop(tp, errno); } /* diff -ru sys/netinet.old/tcp_var.h sys/netinet/tcp_var.h --- sys/netinet.old/tcp_var.h Sun Dec 17 18:57:24 2000 +++ sys/netinet/tcp_var.h Sun Dec 17 23:17:55 2000 @@ -387,7 +387,7 @@ void tcp_input __P((struct mbuf *, int, int)); void tcp_mss __P((struct tcpcb *, int)); int tcp_mssopt __P((struct tcpcb *)); -void tcp_drop_syn_sent __P((struct inpcb *, int)); +void tcp_drop_icmp_unreach __P((struct inpcb *, int)); void tcp_mtudisc __P((struct inpcb *, int)); struct tcpcb * tcp_newtcpcb __P((struct inpcb *)); diff -ru sys/netinet.old/udp_usrreq.c sys/netinet/udp_usrreq.c --- sys/netinet.old/udp_usrreq.c Sun Dec 17 18:57:24 2000 +++ sys/netinet/udp_usrreq.c Sun Dec 17 19:59:53 2000 @@ -512,9 +512,9 @@ 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); + cmd, udp_notify, 0); } else - in_pcbnotify(&udb, sa, 0, zeroin_addr, 0, cmd, udp_notify); + in_pcbnotify(&udb, sa, 0, zeroin_addr, 0, cmd, udp_notify, 0); } static int --4Ckj6UjgE2iN1+kY-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe cvs-all" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001217234119.A90024>