googleprojectzero / googleprojectzero/fuzzilli

Allow arbitrary expressions in object and class fields

Open
#490 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Swift
Stars
2.3k
Forks
367
Avg merge
23h 53m
Merged PRs (30d)
1

Description

Currently FuzzIL's object literals and class definitions to not allow executing arbitrary expressions for property values and computed property names. Instead, these operations simply require an existing input:

BeginObjectLiteral
    ObjectLiteralAddComputedProperty v3, v27
EndObjectLiteral

As such, the values need to be computed first, and so during compilation, code such as

let o = {
  [Symbol.toPrimitive]: function () { return this.foo; },
  foo: "bar" + "baz",
};

Becomes

function f0() {
    return this.foo;
}
const v4 = Symbol.toPrimitive;
const v7 = "bar" + "baz";
const o8 = {
    [v4]: f0,
    "foo": v7,
};

While somewhat harder to read, this is semantically identical. However, there are cases where this behavior is observable, for example with a test case such as:

class X {
    static i = 0;
    static j = X.i + 1;
}
console.log(X);

Moreover, there have been bugs in the past where it was necessary to compute expressions inside class/object literals. While Fuzzilli is not the ideal fuzzer for such types of bugs, adding support for these features would still help find similar bugs in the future.

I think the proper way to support this would be by converting the single instructions into block instructions such as

BeginObjectLiteral
    BeginObjectLiteralComputedPropertyName
        v11 <- CreateNamedVariable "Symbol"
        v12 <- GetProperty v11, "toPrimitive"
    BeginObjectLiteralComputedPropertyValue v12
        v13 <- BeginPlainFunction
            ...
        EndPlainFunction
    EndObjectLiteralComputedProperty v13
EndObjectLiteral

Which would then lift to

let o = {
    [Symbol.toPrimitive]: function() { ... },
};

This is adds a bit of bloat, but on the other hand is really flexible and allows us to perform any computation in these contexts. We already support lifting into a "single-expression" context so we can reuse all of that logic in the lifter, and so this change should mostly just affect the FuzzIL operations.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Inspect the FuzzIL operations for object literals and class definitions, then read Sources/Fuzzilli/Lifting/JavaScriptLifter.swift around line 1326, where single-expression lifting is already supported. Done means computed property names and values can execute arbitrary expressions and lift correctly for the object and class examples described in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, swift
Domain
compilers, testing-qa
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.