From 63916e9a234c1e6bbf82cc21b7d2e39cdecb30d0 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 21 Jun 2016 15:25:53 +0100 Subject: [PATCH] Ensure read records are marked as read In some situations (such as when we receive a fragment of an alert) we try to get the next packet but did not mark the current one as read, meaning that we got the same record back again - leading to an infinite loop. Found using the BoringSSL test suite. Reviewed-by: Andy Polyakov --- ssl/record/rec_layer_s3.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index bce82a761c..fa20b35c56 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -1232,8 +1232,10 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, SSL3_RECORD_add_length(rr, -1); } - if (*dest_len < dest_maxlen) + if (*dest_len < dest_maxlen) { + SSL3_RECORD_set_read(rr); goto start; /* fragment was too small */ + } } } @@ -1316,6 +1318,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, (s->session != NULL) && (s->session->cipher != NULL) && !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { SSL3_RECORD_set_length(rr, 0); + SSL3_RECORD_set_read(rr); ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); goto start; } @@ -1342,6 +1345,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, if (alert_level == SSL3_AL_WARNING) { s->s3->warn_alert = alert_descr; + SSL3_RECORD_set_read(rr); if (alert_descr == SSL_AD_CLOSE_NOTIFY) { s->shutdown |= SSL_RECEIVED_SHUTDOWN; return (0); @@ -1372,6 +1376,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); ERR_add_error_data(2, "SSL alert number ", tmp); s->shutdown |= SSL_RECEIVED_SHUTDOWN; + SSL3_RECORD_set_read(rr); SSL_CTX_remove_session(s->session_ctx, s->session); return (0); } else { @@ -1387,6 +1392,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * shutdown */ s->rwstate = SSL_NOTHING; SSL3_RECORD_set_length(rr, 0); + SSL3_RECORD_set_read(rr); return (0); } @@ -1443,6 +1449,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, */ if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION) { SSL3_RECORD_set_length(rr, 0); + SSL3_RECORD_set_read(rr); goto start; } al = SSL_AD_UNEXPECTED_MESSAGE; -- 2.25.1