Blame SOURCES/varnish-6.0.8-CVE-2022-45060.patch

c15cf8
diff --git a/bin/varnishd/http2/cache_http2_hpack.c b/bin/varnishd/http2/cache_http2_hpack.c
c15cf8
index d432629..b0dacb9 100644
c15cf8
--- a/bin/varnishd/http2/cache_http2_hpack.c
c15cf8
+++ b/bin/varnishd/http2/cache_http2_hpack.c
c15cf8
@@ -93,18 +93,25 @@ static h2_error
c15cf8
 h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len)
c15cf8
 {
c15cf8
 	/* XXX: This might belong in cache/cache_http.c */
c15cf8
+	const char *b0;
c15cf8
 	unsigned n;
c15cf8
+	int disallow_empty;
c15cf8
+	char *p;
c15cf8
+	int i;
c15cf8
 
c15cf8
 	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
c15cf8
 	AN(b);
c15cf8
 	assert(namelen >= 2);	/* 2 chars from the ': ' that we added */
c15cf8
 	assert(namelen <= len);
c15cf8
+	
c15cf8
+	disallow_empty = 0;
c15cf8
 
c15cf8
 	if (len > UINT_MAX) {	/* XXX: cache_param max header size */
c15cf8
 		VSLb(hp->vsl, SLT_BogoHeader, "Header too large: %.20s", b);
c15cf8
 		return (H2SE_ENHANCE_YOUR_CALM);
c15cf8
 	}
c15cf8
 
c15cf8
+	b0 = b;
c15cf8
 	if (b[0] == ':') {
c15cf8
 		/* Match H/2 pseudo headers */
c15cf8
 		/* XXX: Should probably have some include tbl for
c15cf8
@@ -113,10 +120,24 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len)
c15cf8
 			b += namelen;
c15cf8
 			len -= namelen;
c15cf8
 			n = HTTP_HDR_METHOD;
c15cf8
+			disallow_empty = 1;
c15cf8
+
c15cf8
+			/* First field cannot contain SP or CTL */
c15cf8
+			for (p = b, i = 0; i < len; p++, i++) {
c15cf8
+				if (vct_issp(*p) || vct_isctl(*p))
c15cf8
+					return (H2SE_PROTOCOL_ERROR);
c15cf8
+			}
c15cf8
 		} else if (!strncmp(b, ":path: ", namelen)) {
c15cf8
 			b += namelen;
c15cf8
 			len -= namelen;
c15cf8
 			n = HTTP_HDR_URL;
c15cf8
+			disallow_empty = 1;
c15cf8
+
c15cf8
+			/* Second field cannot contain LWS or CTL */
c15cf8
+			for (p = b, i = 0; i < len; p++, i++) {
c15cf8
+				if (vct_islws(*p) || vct_isctl(*p))
c15cf8
+					return (H2SE_PROTOCOL_ERROR);
c15cf8
+			}
c15cf8
 		} else if (!strncmp(b, ":scheme: ", namelen)) {
c15cf8
 			/* XXX: What to do about this one? (typically
c15cf8
 			   "http" or "https"). For now set it as a normal
c15cf8
@@ -124,6 +145,15 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len)
c15cf8
 			b++;
c15cf8
 			len-=1;
c15cf8
 			n = hp->nhd;
c15cf8
+
c15cf8
+			for (p = b + namelen, i = 0; i < len-namelen;
c15cf8
+			    p++, i++) {
c15cf8
+				if (vct_issp(*p) || vct_isctl(*p))
c15cf8
+					return (H2SE_PROTOCOL_ERROR);
c15cf8
+			}
c15cf8
+
c15cf8
+			if (!i)
c15cf8
+				return (H2SE_PROTOCOL_ERROR);
c15cf8
 		} else if (!strncmp(b, ":authority: ", namelen)) {
c15cf8
 			b+=6;
c15cf8
 			len-=6;
c15cf8
@@ -160,6 +190,13 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len)
c15cf8
 	hp->hd[n].b = b;
c15cf8
 	hp->hd[n].e = b + len;
c15cf8
 
c15cf8
+	if (disallow_empty && !Tlen(hp->hd[n])) {
c15cf8
+		VSLb(hp->vsl, SLT_BogoHeader,
c15cf8
+		    "Empty pseudo-header %.*s",
c15cf8
+		    (int)namelen, b0);
c15cf8
+		return (H2SE_PROTOCOL_ERROR);
c15cf8
+	}
c15cf8
+
c15cf8
 	return (0);
c15cf8
 }
c15cf8