Welcome! Log In Create A New Profile

Advanced

[nginx] Perl: disabled unrelated calls from variable handlers.

Maxim Dounin
July 12, 2019 10:56AM
details: https://hg.nginx.org/nginx/rev/0cb693b4cbbb
branches:
changeset: 7528:0cb693b4cbbb
user: Maxim Dounin <mdounin@mdounin.ru>
date: Fri Jul 12 15:35:31 2019 +0300
description:
Perl: disabled unrelated calls from variable handlers.

Variable handlers are not expected to send anything to the client, cannot
sleep or read body, and are not expected to modify the request. Added
appropriate protection to prevent accidental foot shooting.

diffstat:

src/http/modules/perl/nginx.xs | 44 ++++++++++++++++++++++++++++
src/http/modules/perl/ngx_http_perl_module.c | 5 +++
src/http/modules/perl/ngx_http_perl_module.h | 1 +
3 files changed, 50 insertions(+), 0 deletions(-)

diffs (164 lines):

diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -110,6 +110,10 @@ status(r, code)

ngx_http_perl_set_request(r, ctx);

+ if (ctx->variable) {
+ croak("status(): cannot be used in variable handler");
+ }
+
r->headers_out.status = SvIV(ST(1));

ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -133,6 +137,10 @@ send_http_header(r, ...)
croak("send_http_header(): called after error");
}

+ if (ctx->variable) {
+ croak("send_http_header(): cannot be used in variable handler");
+ }
+
if (r->headers_out.status == 0) {
r->headers_out.status = NGX_HTTP_OK;
}
@@ -400,6 +408,10 @@ has_request_body(r, next)

ngx_http_perl_set_request(r, ctx);

+ if (ctx->variable) {
+ croak("has_request_body(): cannot be used in variable handler");
+ }
+
if (ctx->next) {
croak("has_request_body(): another handler active");
}
@@ -526,6 +538,10 @@ discard_request_body(r)

ngx_http_perl_set_request(r, ctx);

+ if (ctx->variable) {
+ croak("discard_request_body(): cannot be used in variable handler");
+ }
+
rc = ngx_http_discard_request_body(r);

if (rc != NGX_OK) {
@@ -551,6 +567,10 @@ header_out(r, key, value)
croak("header_out(): called after error");
}

+ if (ctx->variable) {
+ croak("header_out(): cannot be used in variable handler");
+ }
+
key = ST(1);
value = ST(2);

@@ -640,6 +660,10 @@ print(r, ...)
croak("print(): called after error");
}

+ if (ctx->variable) {
+ croak("print(): cannot be used in variable handler");
+ }
+
if (items == 2) {

/*
@@ -750,6 +774,10 @@ sendfile(r, filename, offset = -1, bytes
croak("sendfile(): called after error");
}

+ if (ctx->variable) {
+ croak("sendfile(): cannot be used in variable handler");
+ }
+
filename = SvPV_nolen(ST(1));

if (filename == NULL) {
@@ -852,6 +880,10 @@ flush(r)
croak("flush(): called after error");
}

+ if (ctx->variable) {
+ croak("flush(): cannot be used in variable handler");
+ }
+
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
ctx->error = 1;
@@ -883,6 +915,10 @@ internal_redirect(r, uri)

ngx_http_perl_set_request(r, ctx);

+ if (ctx->variable) {
+ croak("internal_redirect(): cannot be used in variable handler");
+ }
+
uri = ST(1);

if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) {
@@ -911,6 +947,10 @@ allow_ranges(r)

ngx_http_perl_set_request(r, ctx);

+ if (ctx->variable) {
+ croak("allow_ranges(): cannot be used in variable handler");
+ }
+
r->allow_ranges = 1;


@@ -1097,6 +1137,10 @@ sleep(r, sleep, next)

ngx_http_perl_set_request(r, ctx);

+ if (ctx->variable) {
+ croak("sleep(): cannot be used in variable handler");
+ }
+
if (ctx->next) {
croak("sleep(): another handler active");
}
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -302,6 +302,7 @@ ngx_http_perl_variable(ngx_http_request_

ngx_int_t rc;
ngx_str_t value;
+ ngx_uint_t saved;
ngx_http_perl_ctx_t *ctx;
ngx_http_perl_main_conf_t *pmcf;

@@ -321,6 +322,9 @@ ngx_http_perl_variable(ngx_http_request_
ctx->request = r;
}

+ saved = ctx->variable;
+ ctx->variable = 1;
+
pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module);

value.data = NULL;
@@ -347,6 +351,7 @@ ngx_http_perl_variable(ngx_http_request_
v->not_found = 1;
}

+ ctx->variable = saved;
ctx->filename.data = NULL;
ctx->redirect_uri.len = 0;

diff --git a/src/http/modules/perl/ngx_http_perl_module.h b/src/http/modules/perl/ngx_http_perl_module.h
--- a/src/http/modules/perl/ngx_http_perl_module.h
+++ b/src/http/modules/perl/ngx_http_perl_module.h
@@ -33,6 +33,7 @@ typedef struct {

unsigned done:1;
unsigned error:1;
+ unsigned variable:1;

ngx_array_t *variables; /* array of ngx_http_perl_var_t */

_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[nginx] Perl: disabled unrelated calls from variable handlers.

Maxim Dounin 196 July 12, 2019 10:56AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 230
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready