Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion apache2/apache2_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ void *create_directory_config(apr_pool_t *mp, char *path)

/* Collection timeout */
dcfg->col_timeout = NOT_SET;
dcfg->col_gc_freq = NOT_SET;

dcfg->crypto_key = NOT_SET_P;
dcfg->crypto_key_len = NOT_SET;
Expand Down Expand Up @@ -588,6 +589,9 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
merged->col_timeout = (child->col_timeout == NOT_SET
? parent->col_timeout : child->col_timeout);

merged->col_gc_freq = (child->col_gc_freq == NOT_SET)
? parent->col_gc_freq : child->col_gc_freq;

/* Hash */
merged->crypto_key = (child->crypto_key == NOT_SET_P
? parent->crypto_key : child->crypto_key);
Expand Down Expand Up @@ -730,6 +734,7 @@ void init_directory_config(directory_config *dcfg)
if (dcfg->disable_backend_compression == NOT_SET) dcfg->disable_backend_compression = 0;

if (dcfg->col_timeout == NOT_SET) dcfg->col_timeout = 3600;
if (dcfg->col_gc_freq == NOT_SET) dcfg->col_gc_freq = .01;

/* Hash */
if (dcfg->crypto_key == NOT_SET_P) dcfg->crypto_key = getkey(dcfg->mp);
Expand Down Expand Up @@ -1204,7 +1209,7 @@ static const char *cmd_audit_log(cmd_parms *cmd, void *_dcfg, const char *p1)
else {
const char *file_name = ap_server_root_relative(cmd->pool, dcfg->auditlog_name);
apr_status_t rc;

if (dcfg->auditlog_fileperms == NOT_SET) {
dcfg->auditlog_fileperms = CREATEMODE;
}
Expand Down Expand Up @@ -1492,6 +1497,32 @@ static const char *cmd_collection_timeout(cmd_parms *cmd, void *_dcfg,
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecCollectionTimeout: %s", p1);
}

static const char *cmd_collection_gc_freq(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
directory_config *dcfg = (directory_config *)_dcfg;
float freq;

if (sscanf(p1, "%f", &freq) != 1) {
return "ModSecurity: Invalid value for SecCollectionGCFrequency. Value must be a float.";
}

if (freq <= 0) {
// <= 0 would mean GC would never run.
return "ModSecurity: Invalid value for SecCollectionGCFrequency. Value must be greater than 0.";
}

if (freq > 100) {
// >100 would make no sense.
return "ModSecurity: Invalid value for SecCollectionGCFrequency. Value must be less than 100.";
}

// Convert to percentage
dcfg->col_gc_freq = freq / 100;

return NULL;
}

static const char *cmd_debug_log_level(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
Expand Down Expand Up @@ -3384,6 +3415,14 @@ const command_rec module_directives[] = {
"set default collections timeout. default it 3600"
),

AP_INIT_TAKE12 (
"SecCollectionGCFrequency",
cmd_collection_gc_freq,
NULL,
CMD_SCOPE_ANY,
"set garbage collection frequency. default is to run during roughly 1% of requests."
),

AP_INIT_TAKE1 (
"SecDefaultAction",
cmd_default_action,
Expand Down
4 changes: 2 additions & 2 deletions apache2/modsecurity.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,9 @@ static void modsecurity_persist_data(modsec_rec *msr) {
msr_log(msr, 4, "Recording persistent data took %" APR_TIME_T_FMT
" microseconds.", msr->time_gc);
}

/* Remove stale collections. */
if (rand() < RAND_MAX/100) {
if (ap_random_pick(0, RAND_MAX) < (RAND_MAX * msr->txcfg->col_gc_freq)) {
arr = apr_table_elts(msr->collections);
te = (apr_table_entry_t *)arr->elts;
for (i = 0; i < arr->nelts; i++) {
Expand Down
1 change: 1 addition & 0 deletions apache2/modsecurity.h
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ struct directory_config {

/* Collection timeout */
int col_timeout;
float col_gc_freq;

/* hash of ids */
apr_hash_t *rule_id_htab;
Expand Down