Njs: Import segfault.

Created on 10 Dec 2019  路  3Comments  路  Source: nginx/njs

> cat  wrap.js
import foo from "bundle.js";

> cat bundle.js
var foo = (function(){                                                                                                                  
    return (function f() {})                                                                                                            
});                                                                                                                                     

foo()({1:[]})                                                                                                                           

export default { }

> build/njs wrap.js
Segmentation fault (core dumped)
bug

Most helpful comment

@xeioex

The patch of this issue.

# HG changeset patch
# User hongzhidao <[email protected]>
# Date 1576212457 -28800
# Node ID 498c18c48e84d25d0b36c50fe5b3e3a5379d1966
# Parent  5bf71dfc052fdc8e473e02aa6277d23fe328e83f
Fixed import segfault.

diff -r 5bf71dfc052f -r 498c18c48e84 src/njs_module.c
--- a/src/njs_module.c  Wed Dec 11 15:58:05 2019 +0300
+++ b/src/njs_module.c  Fri Dec 13 12:47:37 2019 +0800
@@ -175,6 +175,7 @@
         goto fail;
     }

+    module->function.args_offset = 1;
     module->function.u.lambda = parser->node->u.value.data.u.lambda;

     njs_mp_free(vm->mem_pool, text.start);
diff -r 5bf71dfc052f -r 498c18c48e84 test/module/lib1.js
--- a/test/module/lib1.js   Wed Dec 11 15:58:05 2019 +0300
+++ b/test/module/lib1.js   Fri Dec 13 12:47:37 2019 +0800
@@ -1,3 +1,9 @@
+var foo = (function(){
+    return (function f() {})
+});
+
+foo()({1:[]})
+
 function hash() {
     var h = crypto.createHash('md5');
     var v = h.update('AB').digest('hex');

The reason is:

  1. modules are regarded as lambda functions.
  2. incorrect allocation in njs_function_lambda_frame.
 428     size = njs_frame_size(closures)
 429            + (function->args_offset + max_args) * sizeof(njs_value_t)
 430            + lambda->local_size;

Notice that function->args_offset is 0 now. It should be 1.

BTW, how do you find this bug?

All 3 comments

@xeioex

Assign this to me :)

> cat bundle.js
function foo() {
}

foo({1:[]})

export default { }

@xeioex

The patch of this issue.

# HG changeset patch
# User hongzhidao <[email protected]>
# Date 1576212457 -28800
# Node ID 498c18c48e84d25d0b36c50fe5b3e3a5379d1966
# Parent  5bf71dfc052fdc8e473e02aa6277d23fe328e83f
Fixed import segfault.

diff -r 5bf71dfc052f -r 498c18c48e84 src/njs_module.c
--- a/src/njs_module.c  Wed Dec 11 15:58:05 2019 +0300
+++ b/src/njs_module.c  Fri Dec 13 12:47:37 2019 +0800
@@ -175,6 +175,7 @@
         goto fail;
     }

+    module->function.args_offset = 1;
     module->function.u.lambda = parser->node->u.value.data.u.lambda;

     njs_mp_free(vm->mem_pool, text.start);
diff -r 5bf71dfc052f -r 498c18c48e84 test/module/lib1.js
--- a/test/module/lib1.js   Wed Dec 11 15:58:05 2019 +0300
+++ b/test/module/lib1.js   Fri Dec 13 12:47:37 2019 +0800
@@ -1,3 +1,9 @@
+var foo = (function(){
+    return (function f() {})
+});
+
+foo()({1:[]})
+
 function hash() {
     var h = crypto.createHash('md5');
     var v = h.update('AB').digest('hex');

The reason is:

  1. modules are regarded as lambda functions.
  2. incorrect allocation in njs_function_lambda_frame.
 428     size = njs_frame_size(closures)
 429            + (function->args_offset + max_args) * sizeof(njs_value_t)
 430            + lambda->local_size;

Notice that function->args_offset is 0 now. It should be 1.

BTW, how do you find this bug?

@hongzhidao

BTW, how do you find this bug?

We are working on using node.js modules directly, using browserify tool. Tried to use protobufjs (8k lines of code) module for nginx healthchecks + grpc backends. All the bugs added recently were found while working on it.

Was this page helpful?
0 / 5 - 0 ratings