From 3dc8c15adc23456f494fd23455b2251efe275eda Mon Sep 17 00:00:00 2001 From: Martin Blix Grydeland 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++) {