CVE-2024-29489 (published 2024-03-28T23:15Z)

Jerryscript 2.4.0 has SEGV at ./jerry-core/ecma/base/ecma-helpers.c:238:58 in ecma_get_object_type.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/jerryscript-project/jerryscript
commit_details: repo_url: https://github.com/jerryscript-project/jerryscript
author: Máté Tokodi
author_date: 2024-03-13 12:08:41+01:00
msg: Fix rare crash caused by get method of proxy object (#5129)

This fixes #5101
In rare cases the proxy object could get used after
being incorrectly removed by the gc

Add stack checks to the start of all function calls

JerryScript-DCO-1.0-Signed-off-by: Máté Tokodi mate.tokodi@szteszoftver.hu
repository: repo_url: https://github.com/jerryscript-project/jerryscript
repo_name: jerryscript-project/jerryscript
description: Ultra-lightweight JavaScript engine for the Internet of Things.
repo_language: C
owner: jerryscript-project
file_changes: filename: gh-actions.yml
change_type: ModificationType.MODIFY
diff: @@ -171,7 +171,7 @@ jobs:
       - run: >-
           $RUNNER -q --jerry-tests
           --buildoptions=--stack-limit=0,--compile-flag=-fsanitize=address,--compile-flag=-m32,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--compile-flag=-O2,--debug,--system-allocator=on,--linker-flag=-fuse-ld=gold
-          --skip-list=parser-oom.js,parser-oom2.js,stack-limit.js,regression-test-issue-4901.js,regression-test-issue-4848.js,regression-test-issue-4890.js,regression-test-issue-2190.js,regression-test-issue-2258-2963.js,regression-test-issue-2448.js,regression-test-issue-2905.js,regression-test-issue-3785.js,proxy-evil-recursion.js
+          --skip-list=parser-oom.js,parser-oom2.js,stack-limit.js,regression-test-issue-4901.js,regression-test-issue-4848.js,regression-test-issue-4890.js,regression-test-issue-2190.js,regression-test-issue-2258-2963.js,regression-test-issue-2448.js,regression-test-issue-2905.js,regression-test-issue-3785.js,proxy-evil-recursion.js,regression-test-issue-5101.js
 
   ASAN_Tests_Debug:
     runs-on: ubuntu-latest
@@ -187,7 +187,7 @@ jobs:
       - run: >-
           $RUNNER -q --jerry-tests --build-debug
           --buildoptions=--stack-limit=0,--compile-flag=-fsanitize=address,--compile-flag=-m32,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--compile-flag=-O2,--debug,--system-allocator=on,--linker-flag=-fuse-ld=gold
-          --skip-list=parser-oom.js,parser-oom2.js,stack-limit.js,regression-test-issue-4901.js,regression-test-issue-4848.js,regression-test-issue-4890.js,regression-test-issue-2190.js,regression-test-issue-2258-2963.js,regression-test-issue-2448.js,regression-test-issue-2905.js,regression-test-issue-3785.js,proxy-evil-recursion.js
+          --skip-list=parser-oom.js,parser-oom2.js,stack-limit.js,regression-test-issue-4901.js,regression-test-issue-4848.js,regression-test-issue-4890.js,regression-test-issue-2190.js,regression-test-issue-2258-2963.js,regression-test-issue-2448.js,regression-test-issue-2905.js,regression-test-issue-3785.js,proxy-evil-recursion.js,regression-test-issue-5101.js
 
   UBSAN_Tests:
     runs-on: ubuntu-latest

programming_language: Shell
filename: ecma-function-object.c
change_type: ModificationType.MODIFY
diff: @@ -1010,6 +1010,8 @@ ecma_op_function_call_constructor (vm_frame_ctx_shared_args_t *shared_args_p, /*
                                    ecma_object_t *scope_p, /**< lexical environment to use */
                                    ecma_value_t this_binding) /**< value of 'ThisBinding' */
 {
+  ECMA_CHECK_STACK_USAGE ();
+
   shared_args_p->header.status_flags |= VM_FRAME_CTX_SHARED_NON_ARROW_FUNC;
 
   ecma_value_t ret_value;
@@ -1080,6 +1082,8 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
 {
   JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
 
+  ECMA_CHECK_STACK_USAGE ();
+
   vm_frame_ctx_shared_args_t shared_args;
   shared_args.header.status_flags = VM_FRAME_CTX_SHARED_HAS_ARG_LIST;
   shared_args.header.function_object_p = func_obj_p;
@@ -1205,6 +1209,8 @@ ecma_op_function_call_native_built_in (ecma_object_t *func_obj_p, /**< Function
 {
   JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION);
 
+  ECMA_CHECK_STACK_USAGE ();
+
 #if JERRY_BUILTIN_REALMS
   ecma_global_object_t *saved_global_object_p = JERRY_CONTEXT (global_object_p);
 
@@ -1235,6 +1241,8 @@ ecma_op_function_call_native (ecma_object_t *func_obj_p, /**< Function object */
 {
   JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
 
+  ECMA_CHECK_STACK_USAGE ();
+
   ecma_native_function_t *native_function_p = (ecma_native_function_t *) func_obj_p;
 
 #if JERRY_BUILTIN_REALMS

programming_language: C
filename: ecma-proxy-object.c
change_type: ModificationType.MODIFY
diff: @@ -1170,7 +1170,9 @@ ecma_proxy_object_get (ecma_object_t *obj_p, /**< proxy object */
   ecma_value_t args[] = { proxy_obj_p->target, prop_value, receiver };
 
   /* 9. */
+  ecma_ref_object (obj_p);
   ecma_value_t trap_result = ecma_op_function_call (func_obj_p, handler, args, 3);
+  ecma_deref_object (obj_p);
 
   ecma_deref_object (func_obj_p);
 

programming_language: C
filename: regression-test-issue-5101.js
change_type: ModificationType.ADD
diff: @@ -0,0 +1,32 @@
+// Copyright JS Foundation and other contributors, http://js.foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+var iter = 100;
+async function f0() {
+    iter--;
+    function f6() {
+        return f0;
+    }
+    var proxy_handler = {
+        "get": f0,
+    };
+
+    f0.__proto__ = new Proxy(f6, proxy_handler);
+
+    if ((iter >= 0)) {
+        var v12 = f0();
+    }
+    return f0;
+}
+f0();

programming_language: Go