This patch addresses an issue brought up by bz@ in D18968:

When TCP_REASS_LOGGING is defined, a NULL pointer dereference would happen,
if user data was received during the TCP handshake and BB logging is used.

A KASSERT is also added to detect tcp_reass() calls with illegal parameter
combinations.

Reported by:		bz@
Reviewed by:		rrs@
MFC after:		3 days
Sponsored by:		Netflix, Inc.
Differential Revision:	https://reviews.freebsd.org/D19254
This commit is contained in:
tuexen 2019-02-21 09:34:47 +00:00
parent 61c06858a1
commit 192c95e996

View File

@ -542,6 +542,10 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, tcp_seq *seq_start,
* and should be rewritten (see NetBSD for optimizations). * and should be rewritten (see NetBSD for optimizations).
*/ */
KASSERT(th == NULL || (seq_start != NULL && tlenp != NULL),
("tcp_reass called with illegal parameter combination "
"(tp=%p, th=%p, seq_start=%p, tlenp=%p, m=%p)",
tp, th, seq_start, tlenp, m));
/* /*
* Call with th==NULL after become established to * Call with th==NULL after become established to
* force pre-ESTABLISHED data up to user socket. * force pre-ESTABLISHED data up to user socket.
@ -1062,12 +1066,20 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, tcp_seq *seq_start,
} else { } else {
#ifdef TCP_REASS_LOGGING #ifdef TCP_REASS_LOGGING
tcp_reass_log_new_in(tp, q->tqe_start, q->tqe_len, q->tqe_m, TCP_R_LOG_READ, q); tcp_reass_log_new_in(tp, q->tqe_start, q->tqe_len, q->tqe_m, TCP_R_LOG_READ, q);
tcp_log_reassm(tp, q, NULL, th->th_seq, *tlenp, TCP_R_LOG_READ, 1); if (th != NULL) {
tcp_log_reassm(tp, q, NULL, th->th_seq, *tlenp, TCP_R_LOG_READ, 1);
} else {
tcp_log_reassm(tp, q, NULL, 0, 0, TCP_R_LOG_READ, 1);
}
#endif #endif
sbappendstream_locked(&so->so_rcv, q->tqe_m, 0); sbappendstream_locked(&so->so_rcv, q->tqe_m, 0);
} }
#ifdef TCP_REASS_LOGGING #ifdef TCP_REASS_LOGGING
tcp_log_reassm(tp, q, NULL, th->th_seq, *tlenp, TCP_R_LOG_READ, 2); if (th != NULL) {
tcp_log_reassm(tp, q, NULL, th->th_seq, *tlenp, TCP_R_LOG_READ, 2);
} else {
tcp_log_reassm(tp, q, NULL, 0, 0, TCP_R_LOG_READ, 2);
}
#endif #endif
KASSERT(tp->t_segqmbuflen >= q->tqe_mbuf_cnt, KASSERT(tp->t_segqmbuflen >= q->tqe_mbuf_cnt,
("tp:%p seg queue goes negative", tp)); ("tp:%p seg queue goes negative", tp));
@ -1083,7 +1095,11 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, tcp_seq *seq_start,
tp, &tp->t_segq, tp->t_segqmbuflen); tp, &tp->t_segq, tp->t_segqmbuflen);
#else #else
#ifdef TCP_REASS_LOGGING #ifdef TCP_REASS_LOGGING
tcp_log_reassm(tp, NULL, NULL, th->th_seq, *tlenp, TCP_R_LOG_ZERO, 0); if (th != NULL) {
tcp_log_reassm(tp, NULL, NULL, th->th_seq, *tlenp, TCP_R_LOG_ZERO, 0);
} else {
tcp_log_reassm(tp, NULL, NULL, 0, 0, TCP_R_LOG_ZERO, 0);
}
#endif #endif
tp->t_segqmbuflen = 0; tp->t_segqmbuflen = 0;
#endif #endif