Skip to content

Commit 59a9871

Browse files
defanatorzimmerle
authored andcommitted
Extend PCRE malloc/free wrappers to use nginx pools
1 parent b9d7d27 commit 59a9871

7 files changed

+98
-38
lines changed

src/ngx_http_modsecurity_body_filter.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
146146
if (buffer_fully_loadead == 1)
147147
{
148148
int ret;
149+
ngx_pool_t *old_pool;
149150

150151
for (chain = in; chain != NULL; chain = chain->next)
151152
{
@@ -159,9 +160,9 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
159160
}
160161
}
161162

162-
ngx_http_modsecurity_pcre_malloc_init();
163+
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
163164
msc_process_response_body(ctx->modsec_transaction);
164-
ngx_http_modsecurity_pcre_malloc_done();
165+
ngx_http_modsecurity_pcre_malloc_done(old_pool);
165166

166167
/* XXX: I don't get how body from modsec being transferred to nginx's buffer. If so - after adjusting of nginx's
167168
XXX: body we can proceed to adjust body size (content-length). see xslt_body_filter() for example */

src/ngx_http_modsecurity_common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ extern ngx_module_t ngx_http_modsecurity_module;
9090
int ngx_http_modsecurity_process_intervention (Transaction *transaction, ngx_http_request_t *r);
9191
ngx_http_modsecurity_ctx_t *ngx_http_modsecurity_create_ctx(ngx_http_request_t *r);
9292
char *ngx_str_to_char(ngx_str_t a, ngx_pool_t *p);
93-
void ngx_http_modsecurity_pcre_malloc_init(void);
94-
void ngx_http_modsecurity_pcre_malloc_done(void);
93+
ngx_pool_t *ngx_http_modsecurity_pcre_malloc_init(ngx_pool_t *pool);
94+
void ngx_http_modsecurity_pcre_malloc_done(ngx_pool_t *old_pool);
9595

9696
/* ngx_http_modsecurity_body_filter.c */
9797
ngx_int_t ngx_http_modsecurity_body_filter_init(void);

src/ngx_http_modsecurity_header_filter.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ ngx_http_modsecurity_header_filter(ngx_http_request_t *r)
415415
int ret = 0;
416416
ngx_uint_t status;
417417
char *http_response_ver;
418+
ngx_pool_t *old_pool;
418419

419420

420421
/* XXX: if NOT_MODIFIED, do we need to process it at all? see xslt_header_filter() */
@@ -518,9 +519,9 @@ ngx_http_modsecurity_header_filter(ngx_http_request_t *r)
518519
}
519520
#endif
520521

521-
ngx_http_modsecurity_pcre_malloc_init();
522+
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
522523
msc_process_response_headers(ctx->modsec_transaction, status, http_response_ver);
523-
ngx_http_modsecurity_pcre_malloc_done();
524+
ngx_http_modsecurity_pcre_malloc_done(old_pool);
524525
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
525526
if (ret > 0) {
526527
return ret;

src/ngx_http_modsecurity_log.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ ngx_http_modsecurity_log_handler(ngx_http_request_t *r)
3737
{
3838
ngx_http_modsecurity_ctx_t *ctx = NULL;
3939
ngx_http_modsecurity_loc_conf_t *cf;
40+
ngx_pool_t *old_pool;
4041

4142
dd("catching a new _log_ phase handler");
4243

@@ -65,9 +66,9 @@ ngx_http_modsecurity_log_handler(ngx_http_request_t *r)
6566
}
6667

6768
dd("calling msc_process_logging for %p", ctx);
68-
ngx_http_modsecurity_pcre_malloc_init();
69+
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
6970
msc_process_logging(ctx->modsec_transaction);
70-
ngx_http_modsecurity_pcre_malloc_done();
71+
ngx_http_modsecurity_pcre_malloc_done(old_pool);
7172

7273
return NGX_OK;
7374
}

src/ngx_http_modsecurity_module.c

Lines changed: 77 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "ddebug.h"
2020

2121
#include "ngx_http_modsecurity_common.h"
22+
#include "stdio.h"
2223

2324
static ngx_int_t ngx_http_modsecurity_init(ngx_conf_t *cf);
2425
static 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);
2829
static 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+
3336
static void *(*old_pcre_malloc)(size_t);
3437
static 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)
584628
static void
585629
ngx_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

593644
static void
594645
ngx_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

src/ngx_http_modsecurity_pre_access.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ ngx_http_modsecurity_pre_access_handler(ngx_http_request_t *r)
4545
#if 1
4646
ngx_http_modsecurity_ctx_t *ctx = NULL;
4747
ngx_http_modsecurity_loc_conf_t *cf;
48+
ngx_pool_t *old_pool;
4849

4950
dd("catching a new _preaccess_ phase handler");
5051

@@ -194,9 +195,9 @@ ngx_http_modsecurity_pre_access_handler(ngx_http_request_t *r)
194195

195196
/* XXX: once more -- is body can be modified ? content-length need to be adjusted ? */
196197

197-
ngx_http_modsecurity_pcre_malloc_init();
198+
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
198199
msc_process_request_body(ctx->modsec_transaction);
199-
ngx_http_modsecurity_pcre_malloc_done();
200+
ngx_http_modsecurity_pcre_malloc_done(old_pool);
200201

201202
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
202203
if (ret > 0) {

src/ngx_http_modsecurity_rewrite.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r)
2525
{
2626
ngx_http_modsecurity_ctx_t *ctx = NULL;
2727
ngx_http_modsecurity_loc_conf_t *cf;
28+
ngx_pool_t *old_pool;
2829

2930
cf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module);
3031
if (cf == NULL || cf->enable != 1) {
@@ -82,11 +83,11 @@ ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r)
8283
return NGX_HTTP_INTERNAL_SERVER_ERROR;
8384
}
8485
const char *server_addr = inet_ntoa(((struct sockaddr_in *) connection->sockaddr)->sin_addr);
85-
ngx_http_modsecurity_pcre_malloc_init();
86+
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
8687
ret = msc_process_connection(ctx->modsec_transaction,
8788
client_addr, client_port,
8889
server_addr, server_port);
89-
ngx_http_modsecurity_pcre_malloc_done();
90+
ngx_http_modsecurity_pcre_malloc_done(old_pool);
9091
if (ret != 1){
9192
dd("Was not able to extract connection information.");
9293
}
@@ -129,9 +130,9 @@ ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r)
129130
if (n_uri == (char*)-1 || n_method == (char*)-1) {
130131
return NGX_HTTP_INTERNAL_SERVER_ERROR;
131132
}
132-
ngx_http_modsecurity_pcre_malloc_init();
133+
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
133134
msc_process_uri(ctx->modsec_transaction, n_uri, n_method, http_version);
134-
ngx_http_modsecurity_pcre_malloc_done();
135+
ngx_http_modsecurity_pcre_malloc_done(old_pool);
135136

136137
dd("Processing intervention with the transaction information filled in (uri, method and version)");
137138
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
@@ -178,9 +179,9 @@ ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r)
178179
* to process this information.
179180
*/
180181

181-
ngx_http_modsecurity_pcre_malloc_init();
182+
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
182183
msc_process_request_headers(ctx->modsec_transaction);
183-
ngx_http_modsecurity_pcre_malloc_done();
184+
ngx_http_modsecurity_pcre_malloc_done(old_pool);
184185
dd("Processing intervention with the request headers information filled in");
185186
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
186187
if (ret > 0) {

0 commit comments

Comments
 (0)