[njs] Fixed NULL pointer dereference when processing If-* headers.
noreply at nginx.com
noreply at nginx.com
Tue Jul 8 22:27:02 UTC 2025
details: https://github.com/nginx/njs/commit/a4addc9b3145313f74de31b592e3b36714987ea0
branches: master
commit: a4addc9b3145313f74de31b592e3b36714987ea0
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Mon, 7 Jul 2025 22:40:45 -0700
description:
Fixed NULL pointer dereference when processing If-* headers.
Previously, when processing requests with If-Match and
If-Unmodified-Since headers worker process crashed.
For example with the following code:
try { r.return(200) }
catch (e) { r.internalRedirect() }
The fix is to disable not_modified filter as it was done in
nginx perl module nginx/nginx at d9887ee2.
---
nginx/ngx_http_js_module.c | 8 ++++++++
nginx/t/js_internal_redirect.t | 29 ++++++++++++++++++++++++++++-
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c
index 1e0a927f..45ddf17e 100644
--- a/nginx/ngx_http_js_module.c
+++ b/nginx/ngx_http_js_module.c
@@ -2455,6 +2455,8 @@ ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
return NJS_ERROR;
}
+ r->disable_not_modified = 1;
+
if (ngx_http_send_header(r) == NGX_ERROR) {
return NJS_ERROR;
}
@@ -2738,6 +2740,8 @@ ngx_http_js_ext_return(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
cv.value.data = text.start;
cv.value.len = text.length;
+ r->disable_not_modified = 1;
+
ctx->status = ngx_http_send_response(r, status, NULL, &cv);
if (ctx->status == NGX_ERROR) {
@@ -5445,6 +5449,8 @@ ngx_http_qjs_ext_return(JSContext *cx, JSValueConst this_val,
cv.value.data = body.data;
cv.value.len = body.len;
+ r->disable_not_modified = 1;
+
ctx->status = ngx_http_send_response(r, status, NULL, &cv);
if (ctx->status == NGX_ERROR) {
@@ -5670,6 +5676,8 @@ ngx_http_qjs_ext_send_header(JSContext *cx, JSValueConst this_val,
return JS_ThrowInternalError(cx, "failed to set content type");
}
+ r->disable_not_modified = 1;
+
if (ngx_http_send_header(r) == NGX_ERROR) {
return JS_ThrowInternalError(cx, "failed to send header");
}
diff --git a/nginx/t/js_internal_redirect.t b/nginx/t/js_internal_redirect.t
index abfe79f9..721113bb 100644
--- a/nginx/t/js_internal_redirect.t
+++ b/nginx/t/js_internal_redirect.t
@@ -11,6 +11,7 @@ use warnings;
use strict;
use Test::More;
+use Socket qw/ CRLF /;
BEGIN { use FindBin; chdir($FindBin::Bin); }
@@ -54,6 +55,10 @@ http {
return 200 redirect$arg_b;
}
+ location /destroyed_ctx {
+ js_content test.destroyed_ctx;
+ }
+
location @named {
return 200 named;
}
@@ -87,7 +92,16 @@ $t->write_file('test.js', <<EOF);
}
}
- export default {njs:test_njs, redirect};
+ function destroyed_ctx(r) {
+ try {
+ r.return(200);
+
+ } catch (e) {
+ r.internalRedirect("\@sub");
+ }
+ }
+
+ export default {njs:test_njs, redirect, destroyed_ctx};
EOF
@@ -103,5 +117,18 @@ like(http_get('/test?unsafe=1'), qr/500 Internal Server/s,
'unsafe redirect');
like(http_get('/test?quoted=1'), qr/200 .*redirect/s,
'quoted redirect');
+get('/destroyed_ctx', 'If-Match: tt');
###############################################################################
+
+sub get {
+ my ($url, @headers) = @_;
+ return http(
+ "GET $url HTTP/1.1" . CRLF .
+ 'Host: localhost' . CRLF .
+ 'Connection: close' . CRLF .
+ join(CRLF, @headers) . CRLF . CRLF
+ );
+}
+
+################################################################################
More information about the nginx-devel
mailing list