skip to content
Back to GitHub.com
Home Bounties Research Advisories Get Involved Events
August 18, 2022

GHSL-2022-043: Remote Code Execution (RCE) in the Chrome renderer - CVE-2022-1869

Man Yue Mo

Coordinated Disclosure Timeline

Summary

Type confusion in v8 that can lead to remote code execution in the Chrome renderer.

Product

Chromium

Tested Version

master branch build 76ae53f

Details

Issue 1: Type confusion in handling of accessor in ReduceNamedAccess (GHSL-2022-043)

In ReduceNamedAccess, map is passed to GetPropertyAccessInfo to create PropertyAccessInfo [1]:

      PropertyAccessInfo access_info = broker()->GetPropertyAccessInfo(
          map, feedback.name(), access_mode, dependencies());
      access_infos_for_feedback.push_back(access_info);
    }

In the case of super property access, this map comes from the feedback collected for the lookup_start_object [2]:

  if (!InferMaps(lookup_start_object, effect, &inferred_maps)) {
    for (const MapRef& map : feedback.maps()) {
      inferred_maps.push_back(map);
    }
  }

In the case of an accessor that is a simple api call, this map is then used in AccessorAccessInfoHelper to check for compatibility between the api call and the map [3]:

PropertyAccessInfo AccessorAccessInfoHelper(...) {
  ...

    CallOptimization::HolderLookup lookup;
    Handle<JSObject> holder_handle = broker->CanonicalPersistentHandle(
        optimization.LookupHolderOfExpectedType(
            broker->local_isolate_or_isolate(), receiver_map.object(),   //<------- receiver_map here is the map for `lookup_start_object` from `ReduceNamedAccess`
            &lookup));

ReducedNameAccess will then carry on to try inlining the getter call [4]:

base::Optional<JSNativeContextSpecialization::ValueEffectControl>
JSNativeContextSpecialization::BuildPropertyLoad(
    Node* lookup_start_object, Node* receiver, Node* context, Node* frame_state,
    Node* effect, Node* control, NameRef const& name,
    ZoneVector<Node*>* if_exceptions, PropertyAccessInfo const& access_info) {
  ...
  if (access_info.IsNotFound()) {
    ...
  } else if (access_info.IsFastAccessorConstant() ||
             access_info.IsDictionaryProtoAccessorConstant()) {
    ConvertReceiverMode receiver_mode =
        receiver == lookup_start_object
            ? ConvertReceiverMode::kNotNullOrUndefined
            : ConvertReceiverMode::kAny;
    value =
        InlinePropertyGetterCall(receiver, receiver_mode, context, frame_state,
                                 &effect, &control, if_exceptions, access_info);  //<------- receiver here is used for the inlined call

This will inline the simple api call with receiver, instead of lookup_start_object. By providing a lookup_start_object that passes the LookupHolderOfExpectedType test above and a receiver of a different type, a type confusion occurs.

Impact

This issue can be exploited to gain RCE in the Chrome renderer sandbox by visiting a malicious website.

Resources

  1. https://source.chromium.org/chromium/chromium/src/+/75c36c7712bea160e69de6b87b864dfcebab239e:v8/src/compiler/js-native-context-specialization.cc;l=1125
  2. https://source.chromium.org/chromium/chromium/src/+/75c36c7712bea160e69de6b87b864dfcebab239e:v8/src/compiler/js-native-context-specialization.cc;l=1084
  3. https://source.chromium.org/chromium/chromium/src/+/75c36c7712bea160e69de6b87b864dfcebab239e:v8/src/compiler/access-info.cc;l=573
  4. https://source.chromium.org/chromium/chromium/src/+/75c36c7712bea160e69de6b87b864dfcebab239e:v8/src/compiler/js-native-context-specialization.cc;l=2293
  5. https://chromium.googlesource.com/v8/v8/+/9c3d4b3556b2797fa9d9f4bee915e8502608312f

CVE

Credit

This issue was discovered and reported by GHSL team member @m-y-mo (Man Yue Mo).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2022-043 in any communication regarding this issue.