OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
Bugtraq archives for 3rd quarter (Jul-Sep) 1998: Re: FreeBSD's RST validation

Re: FreeBSD's RST validation

Don Lewis (Don.LewisTSC.TDK.COM)
Mon, 31 Aug 1998 11:55:07 -0700

On Aug 31, 11:24am, Bruce A. Mah wrote:
} Subject: Re: FreeBSD's RST validation
}
} Personally, I had something a little less radical in mind.  Here's some
} context diffs against tcp_input.c in 2.2.7-RELEASE, which I sent to
} security-officerfreebsd.org last night after some quick testing.
}
} Now someone can tell me why this isn't the right solution.  :-)
}
} Bruce.
}
} -----8<-----snip-----8<-----
}
} *** tcp_input.c-dist  Mon May 18 10:12:44 1998
} --- tcp_input.c       Sun Aug 30 21:22:32 1998
} ***************
} *** 809,815 ****
}                               goto dropwithreset;
}               }
}               if (tiflags & TH_RST) {
} !                     if (tiflags & TH_ACK)
}                               tp = tcp_drop(tp, ECONNREFUSED);
}                       goto drop;
}               }
} --- 809,818 ----
}                               goto dropwithreset;
}               }
}               if (tiflags & TH_RST) {
} !                     if ((tiflags & TH_ACK) &&
} !                     /* XXX outside window? XXX */
} !                         (SEQ_GT(ti->ti_ack, tp->iss) &&
} !                          SEQ_LEQ(ti->ti_ack, tp->snd_max)))
}                               tp = tcp_drop(tp, ECONNREFUSED);
}                       goto drop;
}               }

As more data is sent across the connection, the wider the window for
a spoofed RST opens.  Once you send 2 GB, legitimate RSTs no longer
work.  You should probably be comparing against tp->snd_una instead
of tp->iss.

} ***************
} *** 1147,1152 ****
} --- 1150,1159 ----
}       case TCPS_FIN_WAIT_1:
}       case TCPS_FIN_WAIT_2:
}       case TCPS_CLOSE_WAIT:
} +             /* XXX outside window? XXX */
} +             if (SEQ_GEQ(ti->ti_seq, tp->rcv_nxt + tp->rcv_wnd) ||
} +                 SEQ_LT(ti->ti_seq, tp->rcv_nxt))
} +                 goto drop;
}               so->so_error = ECONNRESET;
}       close:
}               tp->t_state = TCPS_CLOSED;