]> git.kaiwu.me - njs.git/commitdiff
Module: fixed heap-use-after-free while module loading.
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 2 Oct 2025 03:07:14 +0000 (20:07 -0700)
committerDmitry Volyntsev <xeioexception@gmail.com>
Thu, 2 Oct 2025 22:18:43 +0000 (15:18 -0700)
Making a copy of file argument because the engine may outlive
current ngx_cycle.

The bug became visible since 283282f (0.8.8).

nginx/ngx_js.c
nginx/t/js_import2.t

index 7d2522bbf8d528147725e41f5e1fd93b1888228c..75a28735d0ed196d437c143a9bf3b1c27142c9a0 100644 (file)
@@ -557,11 +557,17 @@ ngx_engine_njs_init(ngx_engine_t *engine, ngx_engine_opts_t *opts)
     vm_options.backtrace = 1;
     vm_options.addons = opts->u.njs.addons;
     vm_options.metas = opts->u.njs.metas;
-    vm_options.file = opts->file;
     vm_options.argv = ngx_argv;
     vm_options.argc = ngx_argc;
     vm_options.init = 1;
 
+    vm_options.file.start = njs_mp_alloc(engine->pool, opts->file.length);
+    if (vm_options.file.start == NULL) {
+        return NGX_ERROR;
+    }
+
+    ngx_memcpy(vm_options.file.start, opts->file.start, opts->file.length);
+
     vm = njs_vm_create(&vm_options);
     if (vm == NULL) {
         return NGX_ERROR;
@@ -579,7 +585,7 @@ ngx_engine_njs_init(ngx_engine_t *engine, ngx_engine_opts_t *opts)
 
     engine->u.njs.vm = vm;
 
-    return NJS_OK;
+    return NGX_OK;
 }
 
 
index 7fdc624d920f31defd240eb4f2128a613e7c2ae8..c3b4050e7f56808d5c1f0363d2c501e35da84d13 100644 (file)
@@ -64,6 +64,11 @@ http {
             js_content fun;
         }
 
+        location /test_exception {
+            js_import exception.js;
+            js_content exception.nonexistent;
+        }
+
         location /test_var {
             return 200 $test;
         }
@@ -105,6 +110,11 @@ $t->write_file('fun.js', <<EOF);
 
 EOF
 
+$t->write_file('exception.js', <<EOF);
+    export default {nonexistent};
+
+EOF
+
 $t->write_file('main.js', <<EOF);
     function version(r) {
         r.return(200, njs.version);
@@ -127,11 +137,13 @@ like(http_get('/test_lib'), qr/LIB-TEST/s, 'lib.test');
 like(http_get('/test_fun'), qr/FUN-TEST/s, 'fun');
 like(http_get('/proxy/test_fun'), qr/FUN-TEST/s, 'proxy fun');
 like(http_get('/test_var'), qr/P-TEST/s, 'foo.bar.p');
+http_get('/test_exception');
+http_get('/test_exception');
 
 $t->stop();
 
 my $content = $t->read_file('error.log');
 my $count = () = $content =~ m/js vm init/g;
-ok($count == 4, 'uniq js vm contexts');
+ok($count == 5, 'uniq js vm contexts');
 
 ###############################################################################