CVE-2023-23556 (published 2023-05-18T22:15Z)

An error in BigInt conversion to Number in Hermes prior to commit a6dcafe6ded8e61658b40f5699878cd19a481f80 could have been used by a malicious attacker to execute arbitrary code due to an out-of-bound write. Note that this bug is only exploitable in cases where Hermes is used to execute untrusted JavaScript. Hence, most React Native applications are not affected.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-787
cwe_name: Out-of-bounds Write
description: The product writes data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/facebook/hermes
commit_details: repo_url: https://github.com/facebook/hermes
author: Facebook Community Bot
author_date: 2023-02-02 15:07:13-05:00
msg: Re-sync with internal repository (#908)

Fixes for CVE-2023-23556, and CVE-2023-24833.

Co-authored-by: Facebook Community Bot <6422482+facebook-github-bot@users.noreply.github.com>
repository: repo_url: https://github.com/facebook/hermes
repo_name: facebook/hermes
description: A JavaScript engine optimized for running React Native.
repo_language: C++
owner: facebook
file_changes: filename: BigIntSupport.cpp
change_type: ModificationType.MODIFY
diff: @@ -192,7 +192,11 @@ double toDouble(ImmutableBigIntRef src) {
   const uint32_t numBits = src.numDigits * BigIntDigitSizeInBits;
   llvh::APInt tmp(numBits, llvh::makeArrayRef(src.digits, src.numDigits));
   constexpr bool kSigned = true;
-  return tmp.roundToDouble(kSigned);
+  double val = tmp.roundToDouble(kSigned);
+  // TODO(T142034196): APInt::roundToDouble doesn't implement proper conversion
+  // when the number has more than 2 digits; we need to implement this
+  // conversion.
+  return std::isnan(val) ? std::numeric_limits<double>::quiet_NaN() : val;
 }
 
 namespace {

programming_language: C++
filename: Array.cpp
change_type: ModificationType.MODIFY
diff: @@ -1093,10 +1093,6 @@ class StandardSortModel : public SortModel {
     JSObject::getComputedPrimitiveDescriptor(
         obj_, runtime_, aHandle_, aDescObjHandle_, aTmpNameStorage_, aDesc);
 
-    ComputedPropertyDescriptor bDesc;
-    JSObject::getComputedPrimitiveDescriptor(
-        obj_, runtime_, bHandle_, bDescObjHandle_, bTmpNameStorage_, bDesc);
-
     if (aDescObjHandle_) {
       if (LLVM_LIKELY(!aDesc.flags.proxyObject)) {
         auto res = JSObject::getComputedPropertyValue_RJS(
@@ -1135,6 +1131,11 @@ class StandardSortModel : public SortModel {
         }
       }
     }
+
+    ComputedPropertyDescriptor bDesc;
+    JSObject::getComputedPrimitiveDescriptor(
+        obj_, runtime_, bHandle_, bDescObjHandle_, bTmpNameStorage_, bDesc);
+
     if (bDescObjHandle_) {
       if (LLVM_LIKELY(!bDesc.flags.proxyObject)) {
         auto res = JSObject::getComputedPropertyValue_RJS(

programming_language: C++
filename: Operations.cpp
change_type: ModificationType.MODIFY
diff: @@ -1272,8 +1272,8 @@ addOp_RJS(Runtime &runtime, Handle<> xHandle, Handle<> yHandle) {
 
   return BigIntPrimitive::add(
       runtime,
-      runtime.makeHandle(resX->getBigInt()),
-      runtime.makeHandle(resY->getBigInt()));
+      runtime.makeHandle(xPrim->getBigInt()),
+      runtime.makeHandle(yPrim->getBigInt()));
 }
 
 static const size_t MIN_RADIX = 2;

programming_language: C++
filename: regress-bigint-add-gc.js
change_type: ModificationType.ADD
diff: @@ -0,0 +1,21 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+// RUN: %hermes -non-strict -O %s | %FileCheck %s
+// RUN: %hermes -non-strict -O0 %s | %FileCheck %s
+
+const obj = {
+    toString: () => {
+        gc();
+        return 0n;
+    }
+};
+// trigger after obj.toString called and before addOp complete
+let trigger_point = 1n + obj;
+print(trigger_point);
+
+// CHECK: 1

programming_language: C++
filename: regress-bigint-to-double-nan.js
change_type: ModificationType.ADD
diff: @@ -0,0 +1,13 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+// RUN: %hermes -non-strict -O %s | %FileCheck %s
+// RUN: %hermes -non-strict -O0 %s | %FileCheck %s
+
+// TODO: fix BigInt to number conversion (it should never result in NaN).
+print(Number(0xffffffffffffffffffffffffffffffffn));
+// CHECK: NaN

programming_language: Batchfile
filename: regress-invalidated-descriptor-std-sort-model-swap.js
change_type: ModificationType.ADD
diff: @@ -0,0 +1,20 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+// RUN: %hermes -O %s
+
+var a = [0,1]
+a.sort(function(x,y){
+  a.__defineGetter__(1, function(){
+    delete a[0];
+    return 1;
+  });
+  a.__defineGetter__(0, function(){
+    return 1;
+  });
+  return -1;
+})

programming_language: JavaScript