Skip to content

Commit 3ffa8a3

Browse files
Liu Dongmiaoliudongmiao
Liu Dongmiao
authored andcommitted
lazy load rules set in worker process, avoid memory leak
1 parent 2497e6a commit 3ffa8a3

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

src/ngx_http_modsecurity_common.h

+3
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ typedef struct {
115115
void *pool;
116116
/* RulesSet or Rules */
117117
void *rules_set;
118+
const char *rules;
119+
const char *rules_set_file;
120+
const char *rules_remote_key, *rules_remote_server;
118121

119122
ngx_flag_t enable;
120123
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)

src/ngx_http_modsecurity_module.c

+82-1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,12 @@ ngx_conf_set_rules(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
325325
return NGX_CONF_ERROR;
326326
}
327327

328+
if (!ngx_test_config) {
329+
mcf->rules = rules;
330+
ngx_log_error(NGX_LOG_NOTICE, cf->log, 0, "would lazy-load rules %s", rules);
331+
return NGX_CONF_OK;
332+
}
333+
328334
old_pool = ngx_http_modsecurity_pcre_malloc_init(cf->pool);
329335
res = msc_rules_add(mcf->rules_set, rules, &error);
330336
ngx_http_modsecurity_pcre_malloc_done(old_pool);
@@ -359,6 +365,12 @@ ngx_conf_set_rules_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
359365
return NGX_CONF_ERROR;
360366
}
361367

368+
if (!ngx_test_config) {
369+
mcf->rules_set_file = rules_set;
370+
ngx_log_error(NGX_LOG_NOTICE, cf->log, 0, "would lazy-load rules file %s", rules_set);
371+
return NGX_CONF_OK;
372+
}
373+
362374
old_pool = ngx_http_modsecurity_pcre_malloc_init(cf->pool);
363375
res = msc_rules_add_file(mcf->rules_set, rules_set, &error);
364376
ngx_http_modsecurity_pcre_malloc_done(old_pool);
@@ -398,6 +410,13 @@ ngx_conf_set_rules_remote(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
398410
return NGX_CONF_ERROR;
399411
}
400412

413+
if (!ngx_test_config) {
414+
mcf->rules_remote_key = rules_remote_key;
415+
mcf->rules_remote_server = rules_remote_server;
416+
ngx_log_error(NGX_LOG_NOTICE, cf->log, 0, "would lazy-load remote rules %s", rules_remote_server);
417+
return NGX_CONF_OK;
418+
}
419+
401420
old_pool = ngx_http_modsecurity_pcre_malloc_init(cf->pool);
402421
res = msc_rules_add_remote(mcf->rules_set, rules_remote_key, rules_remote_server, &error);
403422
ngx_http_modsecurity_pcre_malloc_done(old_pool);
@@ -504,14 +523,59 @@ static ngx_http_module_t ngx_http_modsecurity_ctx = {
504523
};
505524

506525

526+
static int load_msc_rules(ngx_http_modsecurity_conf_t *mcf, ngx_log_t *log) {
527+
int rules;
528+
const char *error;
529+
#define show_loaded_rules(message) \
530+
if (rules >= 0) { \
531+
ngx_log_error(NGX_LOG_NOTICE, log, 0, \
532+
"loaded %d rules from %s", rules, message); \
533+
} else { \
534+
goto clean; \
535+
}
536+
537+
if (mcf->rules != NGX_CONF_UNSET_PTR) {
538+
rules = msc_rules_add(mcf->rules_set, mcf->rules, &error);
539+
show_loaded_rules(mcf->rules);
540+
}
541+
if (mcf->rules_set_file != NGX_CONF_UNSET_PTR) {
542+
rules = msc_rules_add_file(mcf->rules_set, mcf->rules_set_file, &error);
543+
show_loaded_rules(mcf->rules_set_file);
544+
}
545+
if (mcf->rules_remote_key != NGX_CONF_UNSET_PTR
546+
&& mcf->rules_remote_server != NGX_CONF_UNSET_PTR) {
547+
rules = msc_rules_add_remote(mcf->rules_set,
548+
mcf->rules_remote_key, mcf->rules_remote_server, &error);
549+
show_loaded_rules(mcf->rules_remote_server);
550+
}
551+
return NGX_OK;
552+
clean:
553+
ngx_log_error(NGX_ERROR_ERR, log, 0, "cannot load rules: %s", error);
554+
return NGX_ERROR;
555+
}
556+
557+
558+
static ngx_int_t ngx_http_modsecurity_init_process(ngx_cycle_t *cycle) {
559+
ngx_pool_cleanup_t *cleanup;
560+
for (cleanup = cycle->pool->cleanup; cleanup; cleanup = cleanup->next) {
561+
if (cleanup->handler == ngx_http_modsecurity_cleanup_rules) {
562+
if (load_msc_rules(cleanup->data, cycle->log) != NGX_OK) {
563+
return NGX_ERROR;
564+
}
565+
}
566+
}
567+
return NGX_OK;
568+
}
569+
570+
507571
ngx_module_t ngx_http_modsecurity_module = {
508572
NGX_MODULE_V1,
509573
&ngx_http_modsecurity_ctx, /* module context */
510574
ngx_http_modsecurity_commands, /* module directives */
511575
NGX_HTTP_MODULE, /* module type */
512576
NULL, /* init master */
513577
NULL, /* init module */
514-
NULL, /* init process */
578+
ngx_http_modsecurity_init_process, /* init process */
515579
NULL, /* init thread */
516580
NULL, /* exit thread */
517581
NULL, /* exit process */
@@ -691,6 +755,10 @@ ngx_http_modsecurity_create_conf(ngx_conf_t *cf)
691755

692756
conf->enable = NGX_CONF_UNSET;
693757
conf->rules_set = msc_create_rules_set();
758+
conf->rules = NGX_CONF_UNSET_PTR;
759+
conf->rules_set_file = NGX_CONF_UNSET_PTR;
760+
conf->rules_remote_key = NGX_CONF_UNSET_PTR;
761+
conf->rules_remote_server = NGX_CONF_UNSET_PTR;
694762
conf->pool = cf->pool;
695763
conf->transaction_id = NGX_CONF_UNSET_PTR;
696764
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
@@ -742,6 +810,19 @@ ngx_http_modsecurity_merge_conf(ngx_conf_t *cf, void *parent, void *child)
742810
dd("CHILD RULES");
743811
msc_rules_dump(c->rules_set);
744812
#endif
813+
814+
#define ngx_conf_merge_ptr_value_if_unset(conf, prev, message) \
815+
if (conf != NGX_CONF_UNSET_PTR && prev != NGX_CONF_UNSET_PTR) { \
816+
return "cannot use " message " on both parent and child"; \
817+
} else { \
818+
ngx_conf_merge_ptr_value(conf, prev, NGX_CONF_UNSET_PTR); \
819+
}
820+
821+
ngx_conf_merge_ptr_value_if_unset(c->rules, p->rules, "modsecurity_rules");
822+
ngx_conf_merge_ptr_value_if_unset(c->rules_set_file, p->rules_set_file, "modsecurity_rules_file");
823+
ngx_conf_merge_ptr_value_if_unset(c->rules_remote_key, p->rules_remote_key, "modsecurity_rules_remote");
824+
ngx_conf_merge_ptr_value_if_unset(c->rules_remote_server, p->rules_remote_server, "modsecurity_rules_remote");
825+
745826
rules = msc_rules_merge(c->rules_set, p->rules_set, &error);
746827

747828
if (rules < 0) {

0 commit comments

Comments
 (0)