From 2a9f5cdb5b5312ddcf16e99a09e164730495d0a0 Mon Sep 17 00:00:00 2001
From: tb <>
Date: Mon, 1 Jun 2020 07:59:49 +0000
Subject: Add a mechanism to set an alert in those parts of the read half of
 the record layer that don't do I/O themselves. Use this mechanism to send a
 record overflow alert for messages that have overlong plaintext or inner
 plaintext.

Fixes most of the remaining record-layer-limits failures of tlsfuzzer.

ok jsing
---
 src/lib/libssl/tls13_record_layer.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/lib/libssl/tls13_record_layer.c b/src/lib/libssl/tls13_record_layer.c
index 5e6f8e1e5b..6c48c93f08 100644
--- a/src/lib/libssl/tls13_record_layer.c
+++ b/src/lib/libssl/tls13_record_layer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_record_layer.c,v 1.47 2020/05/29 17:54:58 jsing Exp $ */
+/* $OpenBSD: tls13_record_layer.c,v 1.48 2020/06/01 07:59:49 tb Exp $ */
 /*
  * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
  *
@@ -52,6 +52,9 @@ struct tls13_record_layer {
 	size_t wrec_appdata_len;
 	size_t wrec_content_len;
 
+	/* Alert to be sent on return from current read handler. */
+	uint8_t alert;
+
 	/* Pending alert messages. */
 	uint8_t *alert_data;
 	size_t alert_len;
@@ -504,6 +507,11 @@ tls13_record_layer_open_record_plaintext(struct tls13_record_layer *rl)
 	if (!tls13_record_content(rl->rrec, &cbs))
 		return 0;
 
+	if (CBS_len(&cbs) > TLS13_RECORD_MAX_PLAINTEXT_LEN) {
+		rl->alert = SSL_AD_RECORD_OVERFLOW;
+		return 0;
+	}
+
 	tls13_record_layer_rbuf_free(rl);
 
 	if (!CBS_stow(&cbs, &rl->rbuf, &rl->rbuf_len))
@@ -548,8 +556,10 @@ tls13_record_layer_open_record_protected(struct tls13_record_layer *rl)
 	    CBS_data(&header), CBS_len(&header)))
 		goto err;
 
-	if (out_len > TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN)
+	if (out_len > TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN) {
+		rl->alert = SSL_AD_RECORD_OVERFLOW;
 		goto err;
+	}
 
 	if (!tls13_record_layer_inc_seq_num(rl->read_seq_num))
 		goto err;
@@ -565,8 +575,10 @@ tls13_record_layer_open_record_protected(struct tls13_record_layer *rl)
 		content_len--;
 	if (content_len < 0)
 		goto err;
-	if (content_len > TLS13_RECORD_MAX_PLAINTEXT_LEN)
+	if (content_len > TLS13_RECORD_MAX_PLAINTEXT_LEN) {
+		rl->alert = SSL_AD_RECORD_OVERFLOW;
 		goto err;
+	}
 	content_type = content[content_len];
 
 	tls13_record_layer_rbuf_free(rl);
@@ -995,6 +1007,9 @@ tls13_record_layer_peek(struct tls13_record_layer *rl, uint8_t content_type,
 		ret = tls13_record_layer_read_internal(rl, content_type, buf, n, 1);
 	} while (ret == TLS13_IO_WANT_RETRY);
 
+	if (rl->alert != 0)
+		return tls13_send_alert(rl, rl->alert);
+
 	return ret;
 }
 
@@ -1008,6 +1023,9 @@ tls13_record_layer_read(struct tls13_record_layer *rl, uint8_t content_type,
 		ret = tls13_record_layer_read_internal(rl, content_type, buf, n, 0);
 	} while (ret == TLS13_IO_WANT_RETRY);
 
+	if (rl->alert != 0)
+		return tls13_send_alert(rl, rl->alert);
+
 	return ret;
 }
 
-- 
cgit v1.2.3-55-g6feb