Skip to content

Commit 578ea98

Browse files
committed
Read fuzzy hash databases on init
Instead of reading the fuzzy db on every invocation, read and store the db contents during initialization and store the contents in memory. The only significant behavior change here is that a change in db contents now (obviously) requires a daemon restart, as no API is provided to flush the list of ssdeep chunks.
1 parent 3690708 commit 578ea98

File tree

2 files changed

+40
-19
lines changed

2 files changed

+40
-19
lines changed

apache2/re.h

+6
Original file line numberDiff line numberDiff line change
@@ -409,8 +409,14 @@ struct msre_cache_rec {
409409
apr_size_t val_len;
410410
};
411411

412+
struct fuzzy_hash_chunk {
413+
const char *data;
414+
struct fuzzy_hash_chunk *next;
415+
};
416+
412417
struct fuzzy_hash_param_data {
413418
const char *file;
419+
struct fuzzy_hash_chunk *head;
414420
int threshold;
415421
};
416422

apache2/re_operators.c

+34-19
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,7 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
12791279
strncmp(fn, "http://", strlen("http://")) == 0)
12801280
{
12811281
*error_msg = apr_psprintf(rule->ruleset->mp, "HTTPS address or " \
1282-
"file path are expected for operator pmFromFile \"%s\"", fn);
1282+
"file path are expected for operator pmFromFile \"%s\"", fn);
12831283
return 0;
12841284
}
12851285
else if (strlen(fn) > strlen("https://") &&
@@ -1316,7 +1316,7 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
13161316
msc_remote_clean_chunk(&chunk);
13171317
#else
13181318
*error_msg = apr_psprintf(rule->ruleset->mp, "ModSecurity was not " \
1319-
"compiled with Curl support, it cannot load: \"%s\"", fn);
1319+
"compiled with Curl support, it cannot load: \"%s\"", fn);
13201320
return 0;
13211321
#endif
13221322
}
@@ -3828,16 +3828,20 @@ static int msre_op_fuzzy_hash_init(msre_rule *rule, char **error_msg)
38283828
{
38293829
#ifdef WITH_SSDEEP
38303830
struct fuzzy_hash_param_data *param_data;
3831+
struct fuzzy_hash_chunk *chunk, *t;
38313832
FILE *fp;
38323833
char *file;
38333834
int param_len,threshold;
3835+
char line[1024];
38343836

38353837
char *data = NULL;
38363838
char *threshold_str = NULL;
38373839

38383840
param_data = apr_palloc(rule->ruleset->mp,
38393841
sizeof(struct fuzzy_hash_param_data));
38403842

3843+
param_data->head = NULL;
3844+
38413845
data = apr_pstrdup(rule->ruleset->mp, rule->op_param);
38423846
threshold_str = data;
38433847
#endif
@@ -3885,6 +3889,28 @@ static int msre_op_fuzzy_hash_init(msre_rule *rule, char **error_msg)
38853889
" %s.", file);
38863890
return -1;
38873891
}
3892+
3893+
while (read_line(line, sizeof(line), fp))
3894+
{
3895+
chunk = apr_palloc(rule->ruleset->mp,
3896+
sizeof(struct fuzzy_hash_chunk));
3897+
3898+
chunk->data = apr_pstrdup(rule->ruleset->mp, line);
3899+
chunk->next = NULL;
3900+
3901+
if (param_data->head == NULL) {
3902+
param_data->head = chunk;
3903+
} else {
3904+
t = param_data->head;
3905+
3906+
while (t->next) {
3907+
t = t->next;
3908+
}
3909+
3910+
t->next = chunk;
3911+
}
3912+
}
3913+
38883914
fclose(fp);
38893915

38903916
param_data->file = file;
@@ -3911,8 +3937,7 @@ static int msre_op_fuzzy_hash_execute(modsec_rec *msr, msre_rule *rule,
39113937
#ifdef WITH_SSDEEP
39123938
char result[FUZZY_MAX_RESULT];
39133939
struct fuzzy_hash_param_data *param = rule->op_param_data;
3914-
FILE *fp;
3915-
char line[1024];
3940+
struct fuzzy_hash_chunk *chunk = param->head;
39163941
#endif
39173942

39183943
if (error_msg == NULL)
@@ -3931,29 +3956,19 @@ static int msre_op_fuzzy_hash_execute(modsec_rec *msr, msre_rule *rule,
39313956
return -1;
39323957
}
39333958

3934-
fp = fopen(param->file, "r");
3935-
if (!fp)
3936-
{
3937-
*error_msg = apr_psprintf(rule->ruleset->mp, "Not able to open " \
3938-
"fuzzy hash file: %s", param->file);
3939-
3940-
return 1;
3941-
}
3942-
3943-
while (read_line(line, sizeof(line), fp))
3959+
while (chunk != NULL)
39443960
{
3945-
int i = fuzzy_compare(line, result);
3961+
int i = fuzzy_compare(chunk->data, result);
3962+
msr_log(msr, 9, "%d (%s)", i, chunk->data);
39463963
if (i >= param->threshold)
39473964
{
39483965
*error_msg = apr_psprintf(msr->mp, "Fuzzy hash of %s matched " \
3949-
"with %s (from: %s). Score: %d.", var->name, line,
3966+
"with %s (from: %s). Score: %d.", var->name, chunk->data,
39503967
param->file, i);
3951-
fclose(fp);
39523968
return 1;
39533969
}
3970+
chunk = chunk->next;
39543971
}
3955-
3956-
fclose(fp);
39573972
#else
39583973
*error_msg = apr_psprintf(rule->ruleset->mp, "ModSecurity was not " \
39593974
"compiled with ssdeep support.");

0 commit comments

Comments
 (0)