Bug 1537924 Comment 0 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

pwn2own 2019

Here is the JIT implementation of Array.slice:

  CompilerObject templateObj_;
  gc::InitialHeap initialHeap_;

  MArraySlice(MDefinition* obj, MDefinition* begin, MDefinition* end,
              JSObject* templateObj, gc::InitialHeap initialHeap)
      : MTernaryInstruction(classOpcode, obj, begin, end),
        templateObj_(templateObj),
        initialHeap_(initialHeap) {
    setResultType(MIRType::Object);
  }

 public:
  INSTRUCTION_HEADER(ArraySlice)
  TRIVIAL_NEW_WRAPPERS
  NAMED_OPERANDS((0, object), (1, begin), (2, end))

  JSObject* templateObj() const { return templateObj_; }

  gc::InitialHeap initialHeap() const { return initialHeap_; }

  AliasSet getAliasSet() const override {
    return AliasSet::Store(AliasSet::Element | AliasSet::ObjectFields);
  }
  bool possiblyCalls() const override { return true; }
  bool appendRoots(MRootList& roots) const override {
    return roots.append(templateObj_);
  }

This states that Array.sice does not have side effects, but actually they can be triggered via Symbol.species.

We execute JS that shortens the Array to cause OOB writes later on.
We spray TypedArrays and overwrite a length to gain arb r/w.
We then ROP to execute our shellcode.
pwn2own 2019

Here is the JIT implementation of Array.slice:

```
  CompilerObject templateObj_;
  gc::InitialHeap initialHeap_;

  MArraySlice(MDefinition* obj, MDefinition* begin, MDefinition* end,
              JSObject* templateObj, gc::InitialHeap initialHeap)
      : MTernaryInstruction(classOpcode, obj, begin, end),
        templateObj_(templateObj),
        initialHeap_(initialHeap) {
    setResultType(MIRType::Object);
  }

 public:
  INSTRUCTION_HEADER(ArraySlice)
  TRIVIAL_NEW_WRAPPERS
  NAMED_OPERANDS((0, object), (1, begin), (2, end))

  JSObject* templateObj() const { return templateObj_; }

  gc::InitialHeap initialHeap() const { return initialHeap_; }

  AliasSet getAliasSet() const override {
    return AliasSet::Store(AliasSet::Element | AliasSet::ObjectFields);
  }
  bool possiblyCalls() const override { return true; }
  bool appendRoots(MRootList& roots) const override {
    return roots.append(templateObj_);
  }
```

This states that Array.sice does not have side effects, but actually they can be triggered via Symbol.species.

We execute JS that shortens the Array to cause OOB writes later on.
We spray TypedArrays and overwrite a length to gain arb r/w.
We then ROP to execute our shellcode.

Back to Bug 1537924 Comment 0