1*4882a593SmuzhiyunFrom 119fb187192a9ea13dc90d9d20c215fc82799ab9 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Patrick Monnerat <patrick@monnerat.net> 3*4882a593SmuzhiyunDate: Mon, 13 Feb 2023 08:33:09 +0100 4*4882a593SmuzhiyunSubject: [PATCH] content_encoding: do not reset stage counter for each header 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunTest 418 verifies 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunCloses #10492 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunCVE: CVE-2023-23916 11*4882a593SmuzhiyunUpstream-Status: Backport [https://github.com/curl/curl/commit/119fb187192a9ea13dc.patch] 12*4882a593SmuzhiyunSigned-off-by: Pawan Badganchi <Pawan.Badganchi@kpit.com> 13*4882a593Smuzhiyun--- 14*4882a593Smuzhiyun lib/content_encoding.c | 7 +- 15*4882a593Smuzhiyun lib/urldata.h | 1 + 16*4882a593Smuzhiyun tests/data/Makefile.inc | 2 +- 17*4882a593Smuzhiyun tests/data/test387 | 2 +- 18*4882a593Smuzhiyun tests/data/test418 | 152 ++++++++++++++++++++++++++++++++++++++++ 19*4882a593Smuzhiyun 5 files changed, 158 insertions(+), 6 deletions(-) 20*4882a593Smuzhiyun create mode 100644 tests/data/test418 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun--- a/lib/content_encoding.c 23*4882a593Smuzhiyun+++ b/lib/content_encoding.c 24*4882a593Smuzhiyun@@ -1037,7 +1037,6 @@ CURLcode Curl_build_unencoding_stack(str 25*4882a593Smuzhiyun const char *enclist, int maybechunked) 26*4882a593Smuzhiyun { 27*4882a593Smuzhiyun struct SingleRequest *k = &data->req; 28*4882a593Smuzhiyun- int counter = 0; 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun do { 31*4882a593Smuzhiyun const char *name; 32*4882a593Smuzhiyun@@ -1072,9 +1071,9 @@ CURLcode Curl_build_unencoding_stack(str 33*4882a593Smuzhiyun if(!encoding) 34*4882a593Smuzhiyun encoding = &error_encoding; /* Defer error at stack use. */ 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun- if(++counter >= MAX_ENCODE_STACK) { 37*4882a593Smuzhiyun- failf(data, "Reject response due to %u content encodings", 38*4882a593Smuzhiyun- counter); 39*4882a593Smuzhiyun+ if(k->writer_stack_depth++ >= MAX_ENCODE_STACK) { 40*4882a593Smuzhiyun+ failf(data, "Reject response due to more than %u content encodings", 41*4882a593Smuzhiyun+ MAX_ENCODE_STACK); 42*4882a593Smuzhiyun return CURLE_BAD_CONTENT_ENCODING; 43*4882a593Smuzhiyun } 44*4882a593Smuzhiyun /* Stack the unencoding stage. */ 45*4882a593Smuzhiyun--- a/lib/urldata.h 46*4882a593Smuzhiyun+++ b/lib/urldata.h 47*4882a593Smuzhiyun@@ -682,6 +682,7 @@ struct SingleRequest { 48*4882a593Smuzhiyun struct dohdata *doh; /* DoH specific data for this request */ 49*4882a593Smuzhiyun #endif 50*4882a593Smuzhiyun unsigned char setcookies; 51*4882a593Smuzhiyun+ unsigned char writer_stack_depth; /* Unencoding stack depth. */ 52*4882a593Smuzhiyun BIT(header); /* incoming data has HTTP header */ 53*4882a593Smuzhiyun BIT(content_range); /* set TRUE if Content-Range: was found */ 54*4882a593Smuzhiyun BIT(upload_done); /* set to TRUE when doing chunked transfer-encoding 55*4882a593Smuzhiyun--- a/tests/data/Makefile.inc 56*4882a593Smuzhiyun+++ b/tests/data/Makefile.inc 57*4882a593Smuzhiyun@@ -69,6 +69,7 @@ 58*4882a593Smuzhiyun \ 59*4882a593Smuzhiyun test400 test401 test402 test403 test404 test405 test406 test407 test408 \ 60*4882a593Smuzhiyun test409 test410 \ 61*4882a593Smuzhiyun+test418 \ 62*4882a593Smuzhiyun \ 63*4882a593Smuzhiyun test430 test431 test432 test433 test434 test435 test436 \ 64*4882a593Smuzhiyun \ 65*4882a593Smuzhiyun--- /dev/null 66*4882a593Smuzhiyun+++ b/tests/data/test418 67*4882a593Smuzhiyun@@ -0,0 +1,152 @@ 68*4882a593Smuzhiyun+<testcase> 69*4882a593Smuzhiyun+<info> 70*4882a593Smuzhiyun+<keywords> 71*4882a593Smuzhiyun+HTTP 72*4882a593Smuzhiyun+gzip 73*4882a593Smuzhiyun+</keywords> 74*4882a593Smuzhiyun+</info> 75*4882a593Smuzhiyun+ 76*4882a593Smuzhiyun+# 77*4882a593Smuzhiyun+# Server-side 78*4882a593Smuzhiyun+<reply> 79*4882a593Smuzhiyun+<data nocheck="yes"> 80*4882a593Smuzhiyun+HTTP/1.1 200 OK 81*4882a593Smuzhiyun+Transfer-Encoding: gzip 82*4882a593Smuzhiyun+Transfer-Encoding: gzip 83*4882a593Smuzhiyun+Transfer-Encoding: gzip 84*4882a593Smuzhiyun+Transfer-Encoding: gzip 85*4882a593Smuzhiyun+Transfer-Encoding: gzip 86*4882a593Smuzhiyun+Transfer-Encoding: gzip 87*4882a593Smuzhiyun+Transfer-Encoding: gzip 88*4882a593Smuzhiyun+Transfer-Encoding: gzip 89*4882a593Smuzhiyun+Transfer-Encoding: gzip 90*4882a593Smuzhiyun+Transfer-Encoding: gzip 91*4882a593Smuzhiyun+Transfer-Encoding: gzip 92*4882a593Smuzhiyun+Transfer-Encoding: gzip 93*4882a593Smuzhiyun+Transfer-Encoding: gzip 94*4882a593Smuzhiyun+Transfer-Encoding: gzip 95*4882a593Smuzhiyun+Transfer-Encoding: gzip 96*4882a593Smuzhiyun+Transfer-Encoding: gzip 97*4882a593Smuzhiyun+Transfer-Encoding: gzip 98*4882a593Smuzhiyun+Transfer-Encoding: gzip 99*4882a593Smuzhiyun+Transfer-Encoding: gzip 100*4882a593Smuzhiyun+Transfer-Encoding: gzip 101*4882a593Smuzhiyun+Transfer-Encoding: gzip 102*4882a593Smuzhiyun+Transfer-Encoding: gzip 103*4882a593Smuzhiyun+Transfer-Encoding: gzip 104*4882a593Smuzhiyun+Transfer-Encoding: gzip 105*4882a593Smuzhiyun+Transfer-Encoding: gzip 106*4882a593Smuzhiyun+Transfer-Encoding: gzip 107*4882a593Smuzhiyun+Transfer-Encoding: gzip 108*4882a593Smuzhiyun+Transfer-Encoding: gzip 109*4882a593Smuzhiyun+Transfer-Encoding: gzip 110*4882a593Smuzhiyun+Transfer-Encoding: gzip 111*4882a593Smuzhiyun+Transfer-Encoding: gzip 112*4882a593Smuzhiyun+Transfer-Encoding: gzip 113*4882a593Smuzhiyun+Transfer-Encoding: gzip 114*4882a593Smuzhiyun+Transfer-Encoding: gzip 115*4882a593Smuzhiyun+Transfer-Encoding: gzip 116*4882a593Smuzhiyun+Transfer-Encoding: gzip 117*4882a593Smuzhiyun+Transfer-Encoding: gzip 118*4882a593Smuzhiyun+Transfer-Encoding: gzip 119*4882a593Smuzhiyun+Transfer-Encoding: gzip 120*4882a593Smuzhiyun+Transfer-Encoding: gzip 121*4882a593Smuzhiyun+Transfer-Encoding: gzip 122*4882a593Smuzhiyun+Transfer-Encoding: gzip 123*4882a593Smuzhiyun+Transfer-Encoding: gzip 124*4882a593Smuzhiyun+Transfer-Encoding: gzip 125*4882a593Smuzhiyun+Transfer-Encoding: gzip 126*4882a593Smuzhiyun+Transfer-Encoding: gzip 127*4882a593Smuzhiyun+Transfer-Encoding: gzip 128*4882a593Smuzhiyun+Transfer-Encoding: gzip 129*4882a593Smuzhiyun+Transfer-Encoding: gzip 130*4882a593Smuzhiyun+Transfer-Encoding: gzip 131*4882a593Smuzhiyun+Transfer-Encoding: gzip 132*4882a593Smuzhiyun+Transfer-Encoding: gzip 133*4882a593Smuzhiyun+Transfer-Encoding: gzip 134*4882a593Smuzhiyun+Transfer-Encoding: gzip 135*4882a593Smuzhiyun+Transfer-Encoding: gzip 136*4882a593Smuzhiyun+Transfer-Encoding: gzip 137*4882a593Smuzhiyun+Transfer-Encoding: gzip 138*4882a593Smuzhiyun+Transfer-Encoding: gzip 139*4882a593Smuzhiyun+Transfer-Encoding: gzip 140*4882a593Smuzhiyun+Transfer-Encoding: gzip 141*4882a593Smuzhiyun+Transfer-Encoding: gzip 142*4882a593Smuzhiyun+Transfer-Encoding: gzip 143*4882a593Smuzhiyun+Transfer-Encoding: gzip 144*4882a593Smuzhiyun+Transfer-Encoding: gzip 145*4882a593Smuzhiyun+Transfer-Encoding: gzip 146*4882a593Smuzhiyun+Transfer-Encoding: gzip 147*4882a593Smuzhiyun+Transfer-Encoding: gzip 148*4882a593Smuzhiyun+Transfer-Encoding: gzip 149*4882a593Smuzhiyun+Transfer-Encoding: gzip 150*4882a593Smuzhiyun+Transfer-Encoding: gzip 151*4882a593Smuzhiyun+Transfer-Encoding: gzip 152*4882a593Smuzhiyun+Transfer-Encoding: gzip 153*4882a593Smuzhiyun+Transfer-Encoding: gzip 154*4882a593Smuzhiyun+Transfer-Encoding: gzip 155*4882a593Smuzhiyun+Transfer-Encoding: gzip 156*4882a593Smuzhiyun+Transfer-Encoding: gzip 157*4882a593Smuzhiyun+Transfer-Encoding: gzip 158*4882a593Smuzhiyun+Transfer-Encoding: gzip 159*4882a593Smuzhiyun+Transfer-Encoding: gzip 160*4882a593Smuzhiyun+Transfer-Encoding: gzip 161*4882a593Smuzhiyun+Transfer-Encoding: gzip 162*4882a593Smuzhiyun+Transfer-Encoding: gzip 163*4882a593Smuzhiyun+Transfer-Encoding: gzip 164*4882a593Smuzhiyun+Transfer-Encoding: gzip 165*4882a593Smuzhiyun+Transfer-Encoding: gzip 166*4882a593Smuzhiyun+Transfer-Encoding: gzip 167*4882a593Smuzhiyun+Transfer-Encoding: gzip 168*4882a593Smuzhiyun+Transfer-Encoding: gzip 169*4882a593Smuzhiyun+Transfer-Encoding: gzip 170*4882a593Smuzhiyun+Transfer-Encoding: gzip 171*4882a593Smuzhiyun+Transfer-Encoding: gzip 172*4882a593Smuzhiyun+Transfer-Encoding: gzip 173*4882a593Smuzhiyun+Transfer-Encoding: gzip 174*4882a593Smuzhiyun+Transfer-Encoding: gzip 175*4882a593Smuzhiyun+Transfer-Encoding: gzip 176*4882a593Smuzhiyun+Transfer-Encoding: gzip 177*4882a593Smuzhiyun+Transfer-Encoding: gzip 178*4882a593Smuzhiyun+Transfer-Encoding: gzip 179*4882a593Smuzhiyun+Transfer-Encoding: gzip 180*4882a593Smuzhiyun+Transfer-Encoding: gzip 181*4882a593Smuzhiyun+ 182*4882a593Smuzhiyun+-foo- 183*4882a593Smuzhiyun+</data> 184*4882a593Smuzhiyun+</reply> 185*4882a593Smuzhiyun+ 186*4882a593Smuzhiyun+# 187*4882a593Smuzhiyun+# Client-side 188*4882a593Smuzhiyun+<client> 189*4882a593Smuzhiyun+<server> 190*4882a593Smuzhiyun+http 191*4882a593Smuzhiyun+</server> 192*4882a593Smuzhiyun+ <name> 193*4882a593Smuzhiyun+Response with multiple Transfer-Encoding headers 194*4882a593Smuzhiyun+ </name> 195*4882a593Smuzhiyun+ <command> 196*4882a593Smuzhiyun+http://%HOSTIP:%HTTPPORT/%TESTNUMBER -sS 197*4882a593Smuzhiyun+</command> 198*4882a593Smuzhiyun+</client> 199*4882a593Smuzhiyun+ 200*4882a593Smuzhiyun+# 201*4882a593Smuzhiyun+# Verify data after the test has been "shot" 202*4882a593Smuzhiyun+<verify> 203*4882a593Smuzhiyun+<protocol crlf="yes"> 204*4882a593Smuzhiyun+GET /%TESTNUMBER HTTP/1.1 205*4882a593Smuzhiyun+Host: %HOSTIP:%HTTPPORT 206*4882a593Smuzhiyun+User-Agent: curl/%VERSION 207*4882a593Smuzhiyun+Accept: */* 208*4882a593Smuzhiyun+ 209*4882a593Smuzhiyun+</protocol> 210*4882a593Smuzhiyun+ 211*4882a593Smuzhiyun+# CURLE_BAD_CONTENT_ENCODING is 61 212*4882a593Smuzhiyun+<errorcode> 213*4882a593Smuzhiyun+61 214*4882a593Smuzhiyun+</errorcode> 215*4882a593Smuzhiyun+<stderr mode="text"> 216*4882a593Smuzhiyun+curl: (61) Reject response due to more than 5 content encodings 217*4882a593Smuzhiyun+</stderr> 218*4882a593Smuzhiyun+</verify> 219*4882a593Smuzhiyun+</testcase> 220