Makes `large stream optimization' optional

This commit is contained in:
Felipe Zimmerle 2017-10-05 18:25:52 +00:00
parent 2e9ea0a677
commit 6406e2108d
No known key found for this signature in database
GPG Key ID: E6DFB08CE8B11277
5 changed files with 84 additions and 5 deletions

View File

@ -192,7 +192,6 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Input filter: Reading request body.");
}
if (modsecurity_request_body_start(msr, error_msg) < 0) {
return -1;
}
@ -283,9 +282,14 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
}
if (msr->txcfg->stream_inbody_inspection == 1) {
#ifndef MSC_LARGE_STREAM_INPUT
msr->stream_input_length+=buflen;
modsecurity_request_body_to_stream(msr, buf, buflen, error_msg);
#else
if (modsecurity_request_body_to_stream(msr, buf, buflen, error_msg) < 0) {
return -1;
}
#endif
}
msr->reqbody_length += buflen;

View File

@ -287,7 +287,10 @@ struct modsec_rec {
unsigned int resbody_contains_html;
apr_size_t stream_input_length;
#ifdef MSC_LARGE_STREAM_INPUT
apr_size_t stream_input_allocated_length;
#endif
char *stream_input_data;
apr_size_t stream_output_length;
char *stream_output_data;

View File

@ -428,9 +428,59 @@ 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) {
#ifndef MSC_LARGE_STREAM_INPUT
char *stream_input_body = NULL;
char *data = NULL;
int first_pkt = 0;
#else
apr_size_t allocate_length = 0;
char* allocated = NULL;
#endif
#ifndef MSC_LARGE_STREAM_INPUT
if(msr->stream_input_data == NULL) {
msr->stream_input_data = (char *)calloc(sizeof(char), msr->stream_input_length + 1);
first_pkt = 1;
}
else {
data = (char *)malloc(msr->stream_input_length + 1 - buflen);
if(data == NULL)
return -1;
memset(data, 0, msr->stream_input_length + 1 - buflen);
memcpy(data, msr->stream_input_data, msr->stream_input_length - buflen);
stream_input_body = (char *)realloc(msr->stream_input_data, msr->stream_input_length + 1);
msr->stream_input_data = (char *)stream_input_body;
}
if (msr->stream_input_data == NULL) {
if(data) {
free(data);
data = NULL;
}
*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);
if(first_pkt) {
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;
}
#else
if (msr->stream_input_data == NULL) {
// Is the request body length known beforehand? (requests that are not Transfer-Encoding: chunked)
if (msr->request_content_length > 0) {
@ -458,7 +508,6 @@ apr_status_t modsecurity_request_body_to_stream(modsec_rec *msr, const char *buf
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_length = msr->stream_input_length + buflen;
@ -480,10 +529,10 @@ apr_status_t modsecurity_request_body_to_stream(modsec_rec *msr, const char *buf
}
}
}
// Append buffer to msr->stream_input_data
memcpy(msr->stream_input_data + msr->stream_input_length, buffer, buflen);
msr->stream_input_length += buflen;
#endif
return 1;
}

View File

@ -634,18 +634,25 @@ nextround:
free(msr->stream_input_data);
msr->stream_input_data = NULL;
msr->stream_input_length = 0;
#ifdef MSC_LARGE_STREAM_INPUT
msr->stream_input_allocated_length = 0;
msr->stream_input_data = (char *)malloc(size);
#else
msr->stream_input_data = (char *)malloc(size+1);
#endif
if(msr->stream_input_data == NULL) {
return -1;
}
msr->stream_input_length = size;
#ifdef MSC_LARGE_STREAM_INPUT
msr->stream_input_allocated_length = size;
memset(msr->stream_input_data, 0x0, size);
#else
memset(msr->stream_input_data, 0x0, size+1);
#endif
msr->if_stream_changed = 1;
memcpy(msr->stream_input_data, data, size);

View File

@ -690,6 +690,22 @@ AC_ARG_ENABLE(modsec-api,
modsec_api=
])
# MSC_LARGE_STREAM_INPUT
AC_ARG_ENABLE(large-stream-input,
AS_HELP_STRING([--enable-large-stream-input],
[Enable optimization for large stream input]),
[
if test "$enableval" == "yes"; then
large_stream_input="-DMSC_LARGE_STREAM_INPUT"
MODSEC_EXTRA_CFLAGS="$MODSEC_EXTRA_CFLAGS $large_stream_input"
else
large_stream_input=
fi
],
[
large_stream_input=
])
# Find apxs
AC_MSG_NOTICE(looking for Apache module support via DSO through APXS)
AC_ARG_WITH(apxs,
@ -812,7 +828,7 @@ else
fi
fi
MODSEC_EXTRA_CFLAGS="$pcre_study $pcre_match_limit $pcre_match_limit_recursion $pcre_jit $request_early $htaccess_config $lua_cache $debug_conf $debug_cache $debug_acmp $debug_mem $perf_meas $modsec_api $cpu_type $unique_id $log_filename $log_server $log_collection_delete_problem $log_dechunk $log_stopwatch $log_handler $log_server_context $collection_global_lock"
MODSEC_EXTRA_CFLAGS="$pcre_study $pcre_match_limit $pcre_match_limit_recursion $pcre_jit $request_early $htaccess_config $lua_cache $debug_conf $debug_cache $debug_acmp $debug_mem $perf_meas $modsec_api $cpu_type $unique_id $log_filename $log_server $log_collection_delete_problem $log_dechunk $log_stopwatch $log_handler $log_server_context $collection_global_lock $large_stream_input"
APXS_WRAPPER=build/apxs-wrapper
APXS_EXTRA_CFLAGS=""