CVE-2021-24037 (published 2021-06-15T22:15Z)

A use after free in hermes, while emitting certain error messages, prior to commit d86e185e485b6330216dee8e854455c694e3a36e allows attackers to potentially execute arbitrary code via crafted JavaScript. Note that this is only exploitable if the application using Hermes permits evaluation of untrusted JavaScript. Hence, most React Native applications are not affected.

Severity: HIGH
CVSS v2 base score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
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-416
cwe_name: Use After Free
description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
extended_description: 
             
             
             
			 
             
             
         
         

Fix information:
repo_url: https://github.com/facebook/hermes
commit_details: repo_url: https://github.com/facebook/hermes
author: Riley Dulin
author_date: 2020-08-14 15:37:38-07:00
msg: Fix a bug in transient object property assignment and getUTF16Ref

Summary:
The returned `UTF16Ref` from `StringView::getUTF16Ref` can be invalidated by
appending more contents to the same allocator.
This case was encountered in `transientObjectPutErrorMessage`, resulting in
using free'd memory.

Reviewed By: tmikov

Differential Revision: D23034855

fbshipit-source-id: 4c25a5369934bf3bdfc5582385503f4b87de3792
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: StringView.h
change_type: ModificationType.MODIFY
diff: @@ -319,9 +319,9 @@ class StringView {
   /// If the string is already UTF16, we return the pointer directly;
   /// otherwise (it's ASCII) we copy the string into the end of \p allocator,
   /// and \return a pointer to the beginning of this string in the allocator.
-  /// Note: \p allocator does not need to be empty when passed in. We always
-  /// append.
+  /// \pre allocator must be empty when passed in.
   UTF16Ref getUTF16Ref(llvh::SmallVectorImpl<char16_t> &allocator) const {
+    assert(allocator.empty() && "Shouldn't use a non-empty allocator");
     return getUTF16Ref(allocator, false);
   }
 

programming_language: C++
filename: Interpreter.cpp
change_type: ModificationType.MODIFY
diff: @@ -445,11 +445,12 @@ transientObjectPutErrorMessage(Runtime *runtime, Handle<> base, SymbolID id) {
   StringView valueAsStringPrintable =
       StringPrimitive::createStringView(runtime, valueAsString);
 
-  SmallU16String<32> tmp;
+  SmallU16String<32> tmp1;
+  SmallU16String<32> tmp2;
   return runtime->raiseTypeError(
       TwineChar16("Cannot create property '") + propName + "' on " +
-      baseTypeAsString.getUTF16Ref(tmp) + " '" +
-      valueAsStringPrintable.getUTF16Ref(tmp) + "'");
+      baseTypeAsString.getUTF16Ref(tmp1) + " '" +
+      valueAsStringPrintable.getUTF16Ref(tmp2) + "'");
 }
 
 ExecutionStatus Interpreter::putByIdTransient_RJS(

programming_language: C++