From 3dc8c15adc23456f494fd23455b2251efe275eda Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 15 Aug 2019 10:56:58 +0200
Subject: [PATCH] Fix http1_splitline parsing of 2 field HTTP proto lines using
 NLNL

When parsing a request like this, "GET /\n\n", the first NL would be
overwritten by nul guard inserted after the 2nd field, and the second NL
would be overwritten by the nul guard after the missing 3rd field. This
would cause http1_dissect_hdrs to attempt to decode the body as headers.
---
 bin/varnishd/http1/cache_http1_proto.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index 5d99da47a8..af9ca3898c 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -224,7 +224,7 @@ static uint16_t
 http1_splitline(struct http *hp, struct http_conn *htc, const int *hf,
     unsigned maxhdr)
 {
-	char *p;
+	char *p, *q;
 	int i;
 
 	assert(hf == HTTP1_Req || hf == HTTP1_Resp);
@@ -265,14 +265,19 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf,
 	hp->hd[hf[1]].e = p;
 	if (!Tlen(hp->hd[hf[1]]))
 		return (400);
-	*p++ = '\0';
 
 	/* Skip SP */
+	q = p;
 	for (; vct_issp(*p); p++) {
 		if (vct_isctl(*p))
 			return (400);
 	}
 	hp->hd[hf[2]].b = p;
+	if (q < p)
+		*q = '\0';	/* Nul guard for the 2nd field. If q == p
+				 * (the third optional field is not
+				 * present), the last nul guard will
+				 * cover this field. */
 
 	/* Third field is optional and cannot contain CTL except TAB */
 	for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) {
