1919#include "ddebug.h"
2020
2121#include "ngx_http_modsecurity_common.h"
22+ #include "stdio.h"
2223
2324static ngx_int_t ngx_http_modsecurity_init (ngx_conf_t * cf );
2425static void * ngx_http_modsecurity_create_main_conf (ngx_conf_t * cf );
@@ -28,32 +29,74 @@ static void ngx_http_modsecurity_main_config_cleanup(void *data);
2829static void ngx_http_modsecurity_config_cleanup (void * data );
2930
3031/*
31- * pcre malloc/free hack magic
32+ * PCRE malloc/free workaround, based on
33+ * https://github.com/openresty/lua-nginx-module/blob/master/src/ngx_http_lua_pcrefix.c
3234 */
35+
3336static void * (* old_pcre_malloc )(size_t );
3437static void (* old_pcre_free )(void * ptr );
38+ static ngx_pool_t * ngx_http_modsec_pcre_pool = NULL ;
3539
36- void
37- ngx_http_modsecurity_pcre_malloc_init ( void )
40+ static void *
41+ ngx_http_modsec_pcre_malloc ( size_t size )
3842{
39- old_pcre_malloc = pcre_malloc ;
40- old_pcre_free = pcre_free ;
43+ if (ngx_http_modsec_pcre_pool ) {
44+ return ngx_palloc (ngx_http_modsec_pcre_pool , size );
45+ }
4146
42- pcre_malloc = malloc ;
43- pcre_free = free ;
47+ fprintf (stderr , "error: modsec pcre malloc failed due to empty pcre pool" );
48+
49+ return NULL ;
4450}
4551
46- void
47- ngx_http_modsecurity_pcre_malloc_done (void )
52+ static void
53+ ngx_http_modsec_pcre_free (void * ptr )
4854{
49- if (old_pcre_malloc == NULL )
55+ if (ngx_http_modsec_pcre_pool ) {
56+ ngx_pfree (ngx_http_modsec_pcre_pool , ptr );
5057 return ;
58+ }
59+
60+ #if 0
61+ /* this may happen when called from cleanup handlers */
62+ fprintf (stderr , "error: modsec pcre free failed due to empty pcre pool" );
63+ #endif
64+
65+ return ;
66+ }
67+
68+ ngx_pool_t *
69+ ngx_http_modsecurity_pcre_malloc_init (ngx_pool_t * pool )
70+ {
71+ ngx_pool_t * old_pool ;
72+
73+ if (pcre_malloc != ngx_http_modsec_pcre_malloc ) {
74+ ngx_http_modsec_pcre_pool = pool ;
75+
76+ old_pcre_malloc = pcre_malloc ;
77+ old_pcre_free = pcre_free ;
5178
52- pcre_malloc = old_pcre_malloc ;
53- pcre_free = old_pcre_free ;
79+ pcre_malloc = ngx_http_modsec_pcre_malloc ;
80+ pcre_free = ngx_http_modsec_pcre_free ;
5481
55- old_pcre_malloc = NULL ;
56- old_pcre_free = NULL ;
82+ return NULL ;
83+ }
84+
85+ old_pool = ngx_http_modsec_pcre_pool ;
86+ ngx_http_modsec_pcre_pool = pool ;
87+
88+ return old_pool ;
89+ }
90+
91+ void
92+ ngx_http_modsecurity_pcre_malloc_done (ngx_pool_t * old_pool )
93+ {
94+ ngx_http_modsec_pcre_pool = old_pool ;
95+
96+ if (old_pool == NULL ) {
97+ pcre_malloc = old_pcre_malloc ;
98+ pcre_free = old_pcre_free ;
99+ }
57100}
58101
59102/*
@@ -494,6 +537,7 @@ ngx_http_modsecurity_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
494537{
495538 ngx_http_modsecurity_loc_conf_t * p = NULL ;
496539 ngx_http_modsecurity_loc_conf_t * c = NULL ;
540+ ngx_pool_t * old_pool ;
497541
498542 p = parent ;
499543 c = child ;
@@ -529,9 +573,9 @@ ngx_http_modsecurity_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
529573 if (rules_remote_key == (char * )-1 ) {
530574 return NGX_CONF_ERROR ;
531575 }
532- ngx_http_modsecurity_pcre_malloc_init ();
576+ old_pool = ngx_http_modsecurity_pcre_malloc_init (cf -> pool );
533577 res = msc_rules_add_remote (c -> rules_set , rules_remote_key , rules_remote_server , & error );
534- ngx_http_modsecurity_pcre_malloc_done ();
578+ ngx_http_modsecurity_pcre_malloc_done (old_pool );
535579 dd ("Loading rules from: '%s'" , rules_remote_server );
536580 if (res < 0 ) {
537581 dd ("Failed to load the rules from: '%s' - reason: '%s'" , rules_remote_server , error );
@@ -547,9 +591,9 @@ ngx_http_modsecurity_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
547591 if (rules_set == (char * )-1 ) {
548592 return NGX_CONF_ERROR ;
549593 }
550- ngx_http_modsecurity_pcre_malloc_init ();
594+ old_pool = ngx_http_modsecurity_pcre_malloc_init (cf -> pool );
551595 res = msc_rules_add_file (c -> rules_set , rules_set , & error );
552- ngx_http_modsecurity_pcre_malloc_done ();
596+ ngx_http_modsecurity_pcre_malloc_done (old_pool );
553597 dd ("Loading rules from: '%s'" , rules_set );
554598 if (res < 0 ) {
555599 dd ("Failed to load the rules from: '%s' - reason: '%s'" , rules_set , error );
@@ -565,9 +609,9 @@ ngx_http_modsecurity_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
565609 if (rules == (char * )-1 ) {
566610 return NGX_CONF_ERROR ;
567611 }
568- ngx_http_modsecurity_pcre_malloc_init ();
612+ old_pool = ngx_http_modsecurity_pcre_malloc_init (cf -> pool );
569613 res = msc_rules_add (c -> rules_set , rules , & error );
570- ngx_http_modsecurity_pcre_malloc_done ();
614+ ngx_http_modsecurity_pcre_malloc_done (old_pool );
571615 dd ("Loading rules: '%s'" , rules );
572616 if (res < 0 ) {
573617 dd ("Failed to load the rules: '%s' - reason: '%s'" , rules , error );
@@ -584,20 +628,31 @@ ngx_http_modsecurity_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
584628static void
585629ngx_http_modsecurity_main_config_cleanup (void * data )
586630{
631+ ngx_pool_t * old_pool ;
587632 ngx_http_modsecurity_main_conf_t * cf = data ;
633+
634+ dd ("deleting a main conf %p" , data );
635+
636+ old_pool = ngx_http_modsecurity_pcre_malloc_init (NULL );
588637 msc_cleanup (cf -> modsec );
638+ ngx_http_modsecurity_pcre_malloc_done (old_pool );
639+
589640 cf -> modsec = NULL ;
590641}
591642
592643
593644static void
594645ngx_http_modsecurity_config_cleanup (void * data )
595646{
647+ ngx_pool_t * old_pool ;
596648 ngx_http_modsecurity_loc_conf_t * t = (ngx_http_modsecurity_loc_conf_t * ) data ;
649+
597650 dd ("deleting a loc conf -- RuleSet is: \"%p\"" , t -> rules_set );
598- ngx_http_modsecurity_pcre_malloc_init ();
651+
652+ old_pool = ngx_http_modsecurity_pcre_malloc_init (NULL );
599653 msc_rules_cleanup (t -> rules_set );
600- ngx_http_modsecurity_pcre_malloc_done ();
654+ ngx_http_modsecurity_pcre_malloc_done (old_pool );
655+
601656 t -> rules_set = NULL ;
602657}
603658
0 commit comments