Skip to content

Commit

Permalink
Clamp tcp timer quantities to reasonable ranges.
Browse files Browse the repository at this point in the history
Reported-by: syzbot+259675123340bf46a6de@syzkaller.appspotmail.com
  • Loading branch information
riastradh authored and riastradh committed Aug 6, 2019
1 parent 6eb7fd2 commit 4952945
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 19 deletions.
8 changes: 4 additions & 4 deletions sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
/* $NetBSD: tcp_input.c,v 1.414 2019/06/01 15:18:42 kamil Exp $ */
/* $NetBSD: tcp_input.c,v 1.415 2019/08/06 15:48:18 riastradh Exp $ */

/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
Expand Down Expand Up @@ -148,7 +148,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.414 2019/06/01 15:18:42 kamil Exp $");
__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.415 2019/08/06 15:48:18 riastradh Exp $");

#ifdef _KERNEL_OPT
#include "opt_inet.h"
Expand Down Expand Up @@ -3379,7 +3379,7 @@ tcp_xmit_timer(struct tcpcb *tp, uint32_t rtt)
if (__predict_false(tcp_rttlocal) && tcp_msl_enable
&& tp->t_srtt > tcp_msl_remote_threshold
&& tp->t_msl < tcp_msl_remote) {
tp->t_msl = tcp_msl_remote;
tp->t_msl = MIN(tcp_msl_remote, TCP_MAXMSL);
}
} else {
/*
Expand Down Expand Up @@ -3647,7 +3647,7 @@ syn_cache_timer(void *arg)
* than the keep alive timer would allow, expire it.
*/
sc->sc_rxttot += sc->sc_rxtcur;
if (sc->sc_rxttot >= tcp_keepinit)
if (sc->sc_rxttot >= MIN(tcp_keepinit, TCP_TIMER_MAXTICKS))
goto dropit;

TCP_STATINC(TCP_STAT_SC_RETRANSMITTED);
Expand Down
21 changes: 14 additions & 7 deletions sys/netinet/tcp_subr.c
@@ -1,4 +1,4 @@
/* $NetBSD: tcp_subr.c,v 1.282 2018/12/27 16:59:17 maxv Exp $ */
/* $NetBSD: tcp_subr.c,v 1.283 2019/08/06 15:48:18 riastradh Exp $ */

/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
Expand Down Expand Up @@ -91,7 +91,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.282 2018/12/27 16:59:17 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.283 2019/08/06 15:48:18 riastradh Exp $");

#ifdef _KERNEL_OPT
#include "opt_inet.h"
Expand Down Expand Up @@ -948,11 +948,12 @@ tcp_tcpcb_template(void)
TCPTV_MIN, TCPTV_REXMTMAX);

/* Keep Alive */
tp->t_keepinit = tcp_keepinit;
tp->t_keepidle = tcp_keepidle;
tp->t_keepintvl = tcp_keepintvl;
tp->t_keepcnt = tcp_keepcnt;
tp->t_maxidle = tp->t_keepcnt * tp->t_keepintvl;
tp->t_keepinit = MIN(tcp_keepinit, TCP_TIMER_MAXTICKS);
tp->t_keepidle = MIN(tcp_keepidle, TCP_TIMER_MAXTICKS);
tp->t_keepintvl = MIN(tcp_keepintvl, TCP_TIMER_MAXTICKS);
tp->t_keepcnt = MAX(1, MIN(tcp_keepcnt, TCP_TIMER_MAXTICKS));
tp->t_maxidle = tp->t_keepcnt * MIN(tp->t_keepintvl,
TCP_TIMER_MAXTICKS/tp->t_keepcnt);

/* MSL */
tp->t_msl = TCPTV_MSL;
Expand Down Expand Up @@ -2012,6 +2013,9 @@ tcp_established(struct tcpcb *tp)
break;
}

/* Clamp to a reasonable range. */
tp->t_msl = MIN(tp->t_msl, TCP_MAXMSL);

#ifdef INET6
/* The !tp->t_inpcb lets the compiler know it can't be v4 *and* v6 */
while (!tp->t_inpcb && tp->t_in6pcb) {
Expand Down Expand Up @@ -2041,6 +2045,9 @@ tcp_established(struct tcpcb *tp)
tp->t_msl = tcp_msl_remote ? tcp_msl_remote : TCPTV_MSL;
break;
}

/* Clamp to a reasonable range. */
tp->t_msl = MIN(tp->t_msl, TCP_MAXMSL);
#endif

tp->t_state = TCPS_ESTABLISHED;
Expand Down
8 changes: 7 additions & 1 deletion sys/netinet/tcp_timer.h
@@ -1,4 +1,4 @@
/* $NetBSD: tcp_timer.h,v 1.29 2018/01/19 07:53:01 ozaki-r Exp $ */
/* $NetBSD: tcp_timer.h,v 1.30 2019/08/06 15:48:18 riastradh Exp $ */

/*-
* Copyright (c) 2001, 2005 The NetBSD Foundation, Inc.
Expand Down Expand Up @@ -165,6 +165,12 @@ const char *tcptimers[] =
#define TCP_TIMER_ISARMED(tp, timer) \
callout_active(&(tp)->t_timer[(timer)])

#define TCP_TIMER_MAXTICKS \
(INT_MAX / (hz / PR_SLOWHZ))

#define TCP_MAXMSL \
(TCP_TIMER_MAXTICKS / 2)

/*
* Force a time value to be in a certain range.
*/
Expand Down
18 changes: 11 additions & 7 deletions sys/netinet/tcp_usrreq.c
@@ -1,4 +1,4 @@
/* $NetBSD: tcp_usrreq.c,v 1.224 2019/02/05 04:48:47 mrg Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.225 2019/08/06 15:48:18 riastradh Exp $ */

/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
Expand Down Expand Up @@ -99,7 +99,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.224 2019/02/05 04:48:47 mrg Exp $");
__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.225 2019/08/06 15:48:18 riastradh Exp $");

#ifdef _KERNEL_OPT
#include "opt_inet.h"
Expand Down Expand Up @@ -209,7 +209,8 @@ tcp_getpcb(struct socket *so, struct inpcb **inp,
static void
change_keepalive(struct socket *so, struct tcpcb *tp)
{
tp->t_maxidle = tp->t_keepcnt * tp->t_keepintvl;
tp->t_maxidle = tp->t_keepcnt * MIN(tp->t_keepintvl,
TCP_TIMER_MAXTICKS / tp->t_keepcnt);
TCP_TIMER_DISARM(tp, TCPT_KEEP);
TCP_TIMER_DISARM(tp, TCPT_2MSL);

Expand Down Expand Up @@ -400,7 +401,7 @@ tcp_ctloutput(int op, struct socket *so, struct sockopt *sopt)
error = sockopt_get(sopt, &ui, sizeof(ui));
if (error)
break;
if (ui > 0) {
if (ui > 0 && ui <= TCP_TIMER_MAXTICKS) {
tp->t_keepidle = ui;
change_keepalive(so, tp);
} else
Expand All @@ -411,7 +412,7 @@ tcp_ctloutput(int op, struct socket *so, struct sockopt *sopt)
error = sockopt_get(sopt, &ui, sizeof(ui));
if (error)
break;
if (ui > 0) {
if (ui > 0 && ui <= TCP_TIMER_MAXTICKS) {
tp->t_keepintvl = ui;
change_keepalive(so, tp);
} else
Expand All @@ -422,7 +423,7 @@ tcp_ctloutput(int op, struct socket *so, struct sockopt *sopt)
error = sockopt_get(sopt, &ui, sizeof(ui));
if (error)
break;
if (ui > 0) {
if (ui > 0 && ui <= TCP_TIMER_MAXTICKS) {
tp->t_keepcnt = ui;
change_keepalive(so, tp);
} else
Expand All @@ -433,7 +434,7 @@ tcp_ctloutput(int op, struct socket *so, struct sockopt *sopt)
error = sockopt_get(sopt, &ui, sizeof(ui));
if (error)
break;
if (ui > 0) {
if (ui > 0 && ui <= TCP_TIMER_MAXTICKS) {
tp->t_keepinit = ui;
change_keepalive(so, tp);
} else
Expand Down Expand Up @@ -1961,6 +1962,9 @@ sysctl_tcp_keep(SYSCTLFN_ARGS)
if (error || newp == NULL)
return error;

if (!(tmp > 0 && tmp <= TCP_TIMER_MAXTICKS))
return EINVAL;

mutex_enter(softnet_lock);

*(u_int *)rnode->sysctl_data = tmp;
Expand Down

0 comments on commit 4952945

Please sign in to comment.