mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 19:24:29 +03:00
Preallocate memory when SecStreamInBodyInspection is on. 20x speed improvement for 10mb upload. Also simplified modsecurity_request_body_to_stream.
This commit is contained in:
committed by
Felipe Zimmerle
parent
07c3659ddc
commit
afae690655
@@ -283,7 +283,6 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (msr->txcfg->stream_inbody_inspection == 1) {
|
if (msr->txcfg->stream_inbody_inspection == 1) {
|
||||||
msr->stream_input_length+=buflen;
|
|
||||||
modsecurity_request_body_to_stream(msr, buf, buflen, error_msg);
|
modsecurity_request_body_to_stream(msr, buf, buflen, error_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -287,6 +287,7 @@ struct modsec_rec {
|
|||||||
unsigned int resbody_contains_html;
|
unsigned int resbody_contains_html;
|
||||||
|
|
||||||
apr_size_t stream_input_length;
|
apr_size_t stream_input_length;
|
||||||
|
apr_size_t stream_input_allocated_length;
|
||||||
char *stream_input_data;
|
char *stream_input_data;
|
||||||
apr_size_t stream_output_length;
|
apr_size_t stream_output_length;
|
||||||
char *stream_output_data;
|
char *stream_output_data;
|
||||||
|
@@ -428,55 +428,62 @@ apr_status_t modsecurity_request_body_store(modsec_rec *msr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
apr_status_t modsecurity_request_body_to_stream(modsec_rec *msr, const char *buffer, int buflen, char **error_msg) {
|
apr_status_t modsecurity_request_body_to_stream(modsec_rec *msr, const char *buffer, int buflen, char **error_msg) {
|
||||||
char *stream_input_body = NULL;
|
apr_size_t allocate;
|
||||||
char *data = NULL;
|
char* allocated;
|
||||||
int first_pkt = 0;
|
|
||||||
|
|
||||||
if(msr->stream_input_data == NULL) {
|
if (msr->stream_input_data == NULL) {
|
||||||
msr->stream_input_data = (char *)calloc(sizeof(char), msr->stream_input_length + 1);
|
// Is the request body length is known beforehand? (requests that are not Transfer-Encoding: chunked)
|
||||||
first_pkt = 1;
|
if (msr->request_content_length > 0) {
|
||||||
}
|
allocate = msr->request_content_length;
|
||||||
else {
|
}
|
||||||
|
else {
|
||||||
data = (char *)malloc(msr->stream_input_length + 1 - buflen);
|
// We don't know how this request is going to be, so hope for just buflen to begin with (requests that are Transfer-Encoding: chunked)
|
||||||
|
allocate = buflen;
|
||||||
if(data == NULL)
|
}
|
||||||
return -1;
|
|
||||||
|
allocated = (char*) calloc(allocate, sizeof(char));
|
||||||
memset(data, 0, msr->stream_input_length + 1 - buflen);
|
if (allocated) {
|
||||||
memcpy(data, msr->stream_input_data, msr->stream_input_length - buflen);
|
msr->stream_input_data = allocated;
|
||||||
|
msr->stream_input_allocated_length = allocate;
|
||||||
stream_input_body = (char *)realloc(msr->stream_input_data, msr->stream_input_length + 1);
|
}
|
||||||
|
else {
|
||||||
msr->stream_input_data = (char *)stream_input_body;
|
*error_msg = apr_psprintf(
|
||||||
}
|
msr->mp,
|
||||||
|
"Unable to allocate memory to hold request body on stream. Asked for %" APR_SIZE_T_FMT " bytes.",
|
||||||
if (msr->stream_input_data == NULL) {
|
allocate);
|
||||||
if(data) {
|
return -1;
|
||||||
free(data);
|
}
|
||||||
data = NULL;
|
}
|
||||||
|
else {
|
||||||
|
// Do we need to expand the space we have previously allocated?
|
||||||
|
if ((msr->stream_input_length + buflen) > msr->stream_input_allocated_length) {
|
||||||
|
|
||||||
|
// If this becomes a hotspot again, consider increasing by some percent extra each time, for fewer reallocs
|
||||||
|
allocate = msr->stream_input_length + buflen;
|
||||||
|
|
||||||
|
allocated = (char*) realloc(msr->stream_input_data, allocate);
|
||||||
|
if (allocated) {
|
||||||
|
msr->stream_input_data = allocated;
|
||||||
|
msr->stream_input_allocated_length = allocate;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*error_msg = apr_psprintf(
|
||||||
|
msr->mp,
|
||||||
|
"Unable to reallocate memory to hold request body on stream. Asked for %" APR_SIZE_T_FMT " bytes.",
|
||||||
|
allocate);
|
||||||
|
free(msr->stream_input_data);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*error_msg = apr_psprintf(msr->mp, "Unable to allocate memory to hold request body on stream. Asked for %" APR_SIZE_T_FMT " bytes.",
|
|
||||||
msr->stream_input_length + 1);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(msr->stream_input_data, 0, msr->stream_input_length+1);
|
// Append buffer to msr->stream_input_data
|
||||||
|
memcpy(msr->stream_input_data + msr->stream_input_length, buffer, buflen);
|
||||||
if(first_pkt) {
|
msr->stream_input_length += buflen;
|
||||||
memcpy(msr->stream_input_data, buffer, msr->stream_input_length);
|
|
||||||
} else {
|
|
||||||
memcpy(msr->stream_input_data, data, msr->stream_input_length - buflen);
|
|
||||||
memcpy(msr->stream_input_data+(msr->stream_input_length - buflen), buffer, buflen);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data) {
|
|
||||||
free(data);
|
|
||||||
data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace a bunch of chunks holding a request body with a single large chunk.
|
* Replace a bunch of chunks holding a request body with a single large chunk.
|
||||||
*/
|
*/
|
||||||
@@ -884,15 +891,15 @@ apr_status_t modsecurity_request_body_clear(modsec_rec *msr, char **error_msg) {
|
|||||||
|
|
||||||
if (msr->msc_reqbody_filename != NULL) {
|
if (msr->msc_reqbody_filename != NULL) {
|
||||||
if (keep_body) {
|
if (keep_body) {
|
||||||
/* Move request body (which is a file) to the storage area. */
|
|
||||||
const char *put_filename = NULL;
|
|
||||||
const char *put_basename = NULL;
|
|
||||||
|
|
||||||
if (strcmp(msr->txcfg->upload_dir, msr->txcfg->tmp_dir) == 0) {
|
if (strcmp(msr->txcfg->upload_dir, msr->txcfg->tmp_dir) == 0) {
|
||||||
msr_log(msr, 4, "Not moving file to identical location.");
|
msr_log(msr, 4, "Not moving file to identical location.");
|
||||||
goto nullify;
|
goto nullify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Move request body (which is a file) to the storage area. */
|
||||||
|
const char *put_filename = NULL;
|
||||||
|
const char *put_basename = NULL;
|
||||||
|
|
||||||
/* Construct the new filename. */
|
/* Construct the new filename. */
|
||||||
put_basename = file_basename(msr->msc_reqbody_mp, msr->msc_reqbody_filename);
|
put_basename = file_basename(msr->msc_reqbody_mp, msr->msc_reqbody_filename);
|
||||||
if (put_basename == NULL) {
|
if (put_basename == NULL) {
|
||||||
|
@@ -634,6 +634,7 @@ nextround:
|
|||||||
free(msr->stream_input_data);
|
free(msr->stream_input_data);
|
||||||
msr->stream_input_data = NULL;
|
msr->stream_input_data = NULL;
|
||||||
msr->stream_input_length = 0;
|
msr->stream_input_length = 0;
|
||||||
|
msr->stream_input_allocated_length = 0;
|
||||||
|
|
||||||
msr->stream_input_data = (char *)malloc(size+1);
|
msr->stream_input_data = (char *)malloc(size+1);
|
||||||
|
|
||||||
@@ -642,7 +643,8 @@ nextround:
|
|||||||
}
|
}
|
||||||
|
|
||||||
msr->stream_input_length = size;
|
msr->stream_input_length = size;
|
||||||
memset(msr->stream_input_data, 0x0, size+1);
|
msr->stream_input_allocated_length = size + 1;
|
||||||
|
memset(msr->stream_input_data, 0x0, size + 1);
|
||||||
|
|
||||||
msr->if_stream_changed = 1;
|
msr->if_stream_changed = 1;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user