Skip to content

Commit

Permalink
Makes `large stream optimization' optional
Browse files Browse the repository at this point in the history
  • Loading branch information
Felipe Zimmerle committed Oct 6, 2017
1 parent 2e9ea0a commit 6406e21
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 5 deletions.
6 changes: 5 additions & 1 deletion apache2/apache2_io.c
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions apache2/modsecurity.h
Expand Up @@ -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;
Expand Down
53 changes: 51 additions & 2 deletions apache2/msc_reqbody.c
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;

Expand All @@ -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;
}
Expand Down
9 changes: 8 additions & 1 deletion apache2/re_operators.c
Expand Up @@ -634,18 +634,25 @@ static int msre_op_rsub_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
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);
Expand Down
18 changes: 17 additions & 1 deletion configure.ac
Expand Up @@ -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,
Expand Down Expand Up @@ -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=""
Expand Down

0 comments on commit 6406e21

Please sign in to comment.