mirror of
https://github.com/curl/curl.git
synced 2026-06-04 00:24:15 +03:00
content_encoding: timeout during slow decoding
Check during transfer/content decoding for every MB or so, if the transfer has reached its overall time limit. Error out if so. This is mainly a protectin against compression bombs using way more time than the transfer is allowed to. Normal compression ratios are unlikely to benefit as they need more upstream data where the timeout handling is already in place. Fixes #21603 Reported-by: Joshua Rogers Closes #21758
This commit is contained in:
parent
049ec8a363
commit
1791a08707
1 changed files with 32 additions and 0 deletions
|
|
@ -46,6 +46,7 @@
|
|||
#include <zstd.h>
|
||||
#endif
|
||||
|
||||
#include "connect.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_trc.h"
|
||||
#include "content_encoding.h"
|
||||
|
|
@ -154,6 +155,7 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
|||
z_const Bytef *orig_in = z->next_in;
|
||||
bool done = FALSE;
|
||||
CURLcode result = CURLE_OK; /* Curl_client_write status */
|
||||
int i = 0;
|
||||
|
||||
/* Check state. */
|
||||
if(zp->zlib_init != ZLIB_INIT &&
|
||||
|
|
@ -167,6 +169,15 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
|||
int status; /* zlib status */
|
||||
done = TRUE;
|
||||
|
||||
if(++i > (1024 * 1024 / DECOMPRESS_BUFFER_SIZE)) {
|
||||
/* check every MB of output if we are not exceeding time limit */
|
||||
i = 0;
|
||||
if(Curl_timeleft_ms(data) < 0) {
|
||||
failf(data, "Operation timed out while decoding payload");
|
||||
return exit_zlib(data, z, &zp->zlib_init, CURLE_OPERATION_TIMEDOUT);
|
||||
}
|
||||
}
|
||||
|
||||
/* (re)set buffer for decompressed output for every iteration */
|
||||
z->next_out = (Bytef *)zp->buffer;
|
||||
z->avail_out = DECOMPRESS_BUFFER_SIZE;
|
||||
|
|
@ -412,6 +423,7 @@ static CURLcode brotli_do_write(struct Curl_easy *data,
|
|||
size_t dstleft;
|
||||
CURLcode result = CURLE_OK;
|
||||
BrotliDecoderResult r = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT;
|
||||
int i = 0;
|
||||
|
||||
if(!(type & CLIENTWRITE_BODY) || !nbytes)
|
||||
return Curl_cwriter_write(data, writer->next, type, buf, nbytes);
|
||||
|
|
@ -421,6 +433,16 @@ static CURLcode brotli_do_write(struct Curl_easy *data,
|
|||
|
||||
while((nbytes || r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) &&
|
||||
result == CURLE_OK) {
|
||||
|
||||
if(++i > (1024 * 1024 / DECOMPRESS_BUFFER_SIZE)) {
|
||||
/* check every MB of output if we are not exceeding time limit */
|
||||
i = 0;
|
||||
if(Curl_timeleft_ms(data) < 0) {
|
||||
failf(data, "Operation timed out while decoding payload");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
dst = (uint8_t *)bp->buffer;
|
||||
dstleft = DECOMPRESS_BUFFER_SIZE;
|
||||
r = BrotliDecoderDecompressStream(bp->br,
|
||||
|
|
@ -520,6 +542,7 @@ static CURLcode zstd_do_write(struct Curl_easy *data,
|
|||
ZSTD_inBuffer in;
|
||||
ZSTD_outBuffer out;
|
||||
size_t errorCode;
|
||||
int i = 0;
|
||||
|
||||
if(!(type & CLIENTWRITE_BODY) || !nbytes)
|
||||
return Curl_cwriter_write(data, writer->next, type, buf, nbytes);
|
||||
|
|
@ -529,6 +552,15 @@ static CURLcode zstd_do_write(struct Curl_easy *data,
|
|||
in.size = nbytes;
|
||||
|
||||
for(;;) {
|
||||
if(++i > (1024 * 1024 / DECOMPRESS_BUFFER_SIZE)) {
|
||||
/* check every MB of output if we are not exceeding time limit */
|
||||
i = 0;
|
||||
if(Curl_timeleft_ms(data) < 0) {
|
||||
failf(data, "Operation timed out while decoding payload");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
out.pos = 0;
|
||||
out.dst = zp->buffer;
|
||||
out.size = DECOMPRESS_BUFFER_SIZE;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue