diff --git a/bughog/subject/factory.py b/bughog/subject/factory.py index c5184afe..c0ef6bc3 100644 --- a/bughog/subject/factory.py +++ b/bughog/subject/factory.py @@ -8,6 +8,7 @@ from bughog.subject.js_engine.evaluation_framework import JSEngineEvaluationFramework from bughog.subject.js_engine.v8.subject import V8Subject from bughog.subject.js_engine.v8_sandbox.subject import V8SandboxSubject +from bughog.subject.js_engine.v8_sandbox_testing.subject import V8SandboxTestingSubject from bughog.subject.subject import Subject from bughog.subject.wasm_runtime.evaluation_framework import ( WasmRuntimeEvaluationFramework, @@ -19,7 +20,7 @@ from bughog.subject.web_browser.servo.subject import Servo subjects: dict[str, Any] = { - 'js_engine': {'evaluation_framework': JSEngineEvaluationFramework, 'subjects': [V8Subject(), V8SandboxSubject()]}, + 'js_engine': {'evaluation_framework': JSEngineEvaluationFramework, 'subjects': [V8Subject(), V8SandboxSubject(), V8SandboxTestingSubject()]}, 'wasm_runtime': {'evaluation_framework': WasmRuntimeEvaluationFramework, 'subjects': [WasmtimeSubject()]}, 'web_browser': { 'evaluation_framework': BrowserEvaluationFramework, diff --git a/bughog/subject/js_engine/simulation.py b/bughog/subject/js_engine/simulation.py index 579095eb..d176ee32 100644 --- a/bughog/subject/js_engine/simulation.py +++ b/bughog/subject/js_engine/simulation.py @@ -19,4 +19,4 @@ def report_simulation_error(self, message: str): def run(self, file_name: str): self.executable.run([file_name], cwd=self.context) - self.executable.terminate(wait=True) + self.executable.terminate(wait=True, timeout=30) diff --git a/bughog/subject/js_engine/v8_sandbox_noasan/executable.py b/bughog/subject/js_engine/v8_sandbox_noasan/executable.py new file mode 100644 index 00000000..9f77cc35 --- /dev/null +++ b/bughog/subject/js_engine/v8_sandbox_noasan/executable.py @@ -0,0 +1,18 @@ +from bughog.subject.js_engine.v8.executable import V8Executable + + +class V8SandboxNoAsanExecutable(V8Executable): + def _get_cli_command(self) -> list[str]: + if self.state.commit_nb < 93153: + runtime_flags = [ + "--sandbox-fuzzing" if flag == "--sandbox-testing" else flag + for flag in self._runtime_flags + ] + elif self.state.commit_nb < 97151: + runtime_flags = [ + "--sandbox-testing" if flag == "--sandbox-fuzzing" else flag + for flag in self._runtime_flags + ] + else: + runtime_flags = list(self._runtime_flags) + return [self.executable_path] + runtime_flags diff --git a/bughog/subject/js_engine/v8_sandbox_noasan/subject.py b/bughog/subject/js_engine/v8_sandbox_noasan/subject.py new file mode 100644 index 00000000..65b1500a --- /dev/null +++ b/bughog/subject/js_engine/v8_sandbox_noasan/subject.py @@ -0,0 +1,16 @@ +from bughog.subject.js_engine.v8_sandbox.subject import V8SandboxSubject +from bughog.subject.js_engine.v8_sandbox_noasan.executable import V8SandboxNoAsanExecutable +from bughog.parameters import SubjectConfiguration +from bughog.subject.js_engine.v8.executable import V8Executable +from bughog.version_control.state.base import State + + + +class V8SandboxNoAsanSubject(V8SandboxSubject): + + @property + def name(self) -> str: + return 'v8_sandbox_noasan' + + def create_executable(self, subject_configuration: SubjectConfiguration, state: State) -> V8Executable: + return V8SandboxNoAsanExecutable(subject_configuration, state) diff --git a/bughog/subject/js_engine/v8_sandbox_testing/executable.py b/bughog/subject/js_engine/v8_sandbox_testing/executable.py new file mode 100644 index 00000000..08022a46 --- /dev/null +++ b/bughog/subject/js_engine/v8_sandbox_testing/executable.py @@ -0,0 +1,18 @@ +from bughog.subject.js_engine.v8.executable import V8Executable + + +class V8SandboxTestingExecutable(V8Executable): + def _get_cli_command(self) -> list[str]: + if self.state.commit_nb < 93153: + runtime_flags = [ + "--sandbox-fuzzing" if flag == "--sandbox-testing" else flag + for flag in self._runtime_flags + ] + elif self.state.commit_nb < 97151: + runtime_flags = [ + "--sandbox-testing" if flag == "--sandbox-fuzzing" else flag + for flag in self._runtime_flags + ] + else: + runtime_flags = list(self._runtime_flags) + return [self.executable_path] + runtime_flags diff --git a/bughog/subject/js_engine/v8_sandbox_testing/state_oracle.py b/bughog/subject/js_engine/v8_sandbox_testing/state_oracle.py new file mode 100644 index 00000000..6b525d0c --- /dev/null +++ b/bughog/subject/js_engine/v8_sandbox_testing/state_oracle.py @@ -0,0 +1,109 @@ +import logging +import re + +import requests + +from typing import Literal +from bughog.database.mongo.cache import Cache +from bughog.subject.state_oracle import StateOracle +from bughog.util import http +from bughog.version_control.conversion import bughog_service, github +from bughog.version_control.version import Version + +logger = logging.getLogger(__name__) + + +class V8SandboxTestingStateOracle(StateOracle): + """ + State oracle for V8. + + More information: + - https://v8.dev/docs/version-numbers + - https://commondatastorage.googleapis.com/v8-asan/index.html + """ + + # Commit / revision logic + + @Cache.cache_in_db('js_engine', 'v8') + def find_commit_nb(self, commit_id: str) -> int: + return bughog_service.find_commit_nb('v8', commit_id) + + @Cache.cache_in_db('js_engine', 'v8') + def find_commit_id(self, commit_nb: int) -> str | None: + return bughog_service.find_commit_id('v8', commit_nb) + + @Cache.cache_in_db('js_engine', 'v8') + def find_commit_of_release(self, release_version: Version) -> tuple[int, str]: + # TODO: make more efficient (possibly by adding functionality to bughog service) + all_release_tags = self.__get_all_release_tags() + major_release_tag = self._get_earliest_tag_version_match(all_release_tags, release_version) + commit_id = github.find_commit_id_from_tag('v8', 'v8', major_release_tag) + commit_nb = self.find_commit_nb(commit_id) + return commit_nb, commit_id + + def get_most_recent_commit_nb(self) -> int: + """ + We override this method because we want to call the API for v8, not v8_sandbox. + """ + return bughog_service.find_latest_commit_info('v8')['nb'] + + def get_commit_url(self, commit_nb: int, commit_id: str | None) -> str | None: + if commit_id is None: + return None + return f'https://chromium.googlesource.com/v8/v8/+/{commit_id}' + + # Public executables + + def get_earliest_supported_release_version(self) -> Version: + return Version('6') + + def get_latest_supported_release_version(self) -> Version: + all_release_tags = self.__get_all_release_tags() + versions = list(Version(tag.split('.')[0]) for tag in all_release_tags) + return max(versions) + + @Cache.cache_in_db('js_engine', 'v8_sandbox_testing') + def has_public_release_executable(self, version: Version) -> bool: + for url in self.get_release_executable_urls(version): + resp = requests.head(url, allow_redirects=True) + if resp.status_code == 200: + return True + return False + + @Cache.cache_in_db('js_engine', 'v8_sandbox_testing') + def has_public_commit_executable(self, commit_nb: int) -> bool: + for url in self.get_commit_executable_urls(commit_nb): + resp = requests.head(url, allow_redirects=True) + if resp.status_code == 200: + return True + return False + + def get_nearest_state_with_executable( + self, target_commit_nb: int, lower_bound: int, upper_bound: int, state_type: Literal['release', 'commit'] + ) -> int | None: + if target_commit_nb < 92457: + return 92457 # First commit with available executable + else: + # Currently no further lookup mechanism implemented + raise NotImplementedError() + + @Cache.cache_in_db('js_engine', 'v8_sandbox_testing') + def get_release_executable_urls(self, version: Version) -> list[str]: + commit_nb = self.find_commit_of_release(version)[0] + return self.get_commit_executable_urls(commit_nb) + + @Cache.cache_in_db('js_engine', 'v8_sandbox_testing') + def get_commit_executable_urls(self, commit_nb: int) -> list[str]: + # Debug: + return [ + f'https://storage.googleapis.com/v8-asan/linux-release/d8-sandbox-testing-linux-release-v8-component-{commit_nb}.zip?alt=media', + ] + + @staticmethod + @Cache.cache_in_db('js_engine', 'v8', ttl=24) + def __get_all_release_tags() -> list[str]: + url = 'https://chromium.googlesource.com/v8/v8.git/+refs' + html = http.request_html(url).decode() + all_tags = re.findall(r'/refs/tags/(\d+(?:\.\d+)+)', html) + pattern = re.compile(r'^\d+\.\d+\.\d+$') + return [tag for tag in all_tags if pattern.match(tag)] diff --git a/bughog/subject/js_engine/v8_sandbox_testing/subject.py b/bughog/subject/js_engine/v8_sandbox_testing/subject.py new file mode 100644 index 00000000..32075d0b --- /dev/null +++ b/bughog/subject/js_engine/v8_sandbox_testing/subject.py @@ -0,0 +1,19 @@ +from bughog.parameters import SubjectConfiguration +from bughog.subject.js_engine.subject import JsEngine +from bughog.subject.js_engine.v8_sandbox_testing.executable import V8SandboxTestingExecutable +from bughog.subject.js_engine.v8_sandbox_testing.state_oracle import V8SandboxTestingStateOracle +from bughog.version_control.state.base import State + + +class V8SandboxTestingSubject(JsEngine): + @property + def name(self) -> str: + return 'v8_sandbox_testing' + +# Test Docker build cached + @property + def state_oracle(self) -> V8SandboxTestingStateOracle: + return V8SandboxTestingStateOracle(self.type, self.name) + + def create_executable(self, subject_configuration: SubjectConfiguration, state: State) -> V8SandboxTestingExecutable: + return V8SandboxTestingExecutable(subject_configuration, state) diff --git a/subject/js_engine/experiments/_tests/debug-print-fail/poc.js b/subject/js_engine/experiments/_tests/debug-print-fail/poc.js new file mode 100644 index 00000000..422db00a --- /dev/null +++ b/subject/js_engine/experiments/_tests/debug-print-fail/poc.js @@ -0,0 +1,3 @@ +// bughog_runtime_flags: --allow-natives-syntax +// bughog_expected_output: Something +%DebugPrint("bughog_sanity_check=ok"); \ No newline at end of file diff --git a/subject/js_engine/experiments/_tests/debug-print-success/poc.js b/subject/js_engine/experiments/_tests/debug-print-success/poc.js new file mode 100644 index 00000000..eba67d18 --- /dev/null +++ b/subject/js_engine/experiments/_tests/debug-print-success/poc.js @@ -0,0 +1,3 @@ +// bughog_runtime_flags: --allow-natives-syntax +// bughog_expected_output: bughog_sanity_check=ok +%DebugPrint("bughog_sanity_check=ok"); \ No newline at end of file diff --git a/subject/js_engine/experiments/_tests/fuzzing_param_off/poc.js b/subject/js_engine/experiments/_tests/fuzzing_param_off/poc.js new file mode 100644 index 00000000..7aea902e --- /dev/null +++ b/subject/js_engine/experiments/_tests/fuzzing_param_off/poc.js @@ -0,0 +1,92 @@ +// bughog_runtime_flags: --allow-natives-syntax --expose-gc --omit-quit --jit-fuzzing --future --harmony --js-staging --wasm-staging --experimental-wasm-jspi +// bughog_expected_output: Received signal 11 +%DebugPrint("bughog_sanity_check=ok"); + +function f0() { + // WasmModule Code: + // BeginWasmModule + // BeginWasmFunction [] ([] => .nothing) + // v7 <- EndWasmFunction + // v8 <- EndWasmModule + // + const v8 = new WebAssembly.Instance( + new WebAssembly.Module( + new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x60, + 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x04, 0x01, 0x00, 0x05, 0x01, 0x00, + 0x06, 0x01, 0x00, 0x07, 0x06, 0x01, 0x02, 0x77, 0x30, 0x00, 0x00, 0x0a, + 0x04, 0x01, 0x02, 0x00, 0x0b, + ]) + ) + ); + + let v11 = WebAssembly.promising(v8.exports.w0); + v11(f0, f0); + + console.log("A"); + + // WasmModule Code: + // BeginWasmModule + // BeginWasmFunction [v50, v51, v52, v53, v54] ([.wasmi32, .wasmf64, .wasmi32, .wasmf64, .wasmi32] => .wasmf32) + // v55 <- Constf32 '6.5286493' + // WasmReturn v55 + // v56 <- EndWasmFunction + // v57 <- EndWasmModule + // + const v57 = new WebAssembly.Instance( + new WebAssembly.Module( + new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x01, 0x60, + 0x05, 0x7f, 0x7c, 0x7f, 0x7c, 0x7f, 0x01, 0x7d, 0x03, 0x02, 0x01, 0x00, + 0x04, 0x01, 0x00, 0x05, 0x01, 0x00, 0x06, 0x01, 0x00, 0x07, 0x06, 0x01, + 0x02, 0x77, 0x30, 0x00, 0x00, 0x0a, 0x10, 0x01, 0x0e, 0x01, 0x01, 0x7d, + 0x43, 0xb2, 0xea, 0xd0, 0x40, 0x21, 0x05, 0x20, 0x05, 0x0f, 0x0b, + ]) + ) + ); + console.log("B"); + + // This triggers lazy compilation. + v57.exports.w0(); + console.log("C"); +} +// WasmModule Code: +// BeginWasmModule +// BeginWasmFunction [] ([] => .nothing) +// v102 <- WasmJsCall([] => .wasmi32) v0 [] +// WasmReturn +// v103 <- EndWasmFunction +// v104 <- EndWasmModule +// +const v104 = new WebAssembly.Instance( + new WebAssembly.Module( + new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x60, + 0x00, 0x01, 0x7f, 0x60, 0x00, 0x00, 0x02, 0x17, 0x01, 0x07, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x0b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x5f, 0x30, 0x5f, 0x76, 0x30, 0x00, 0x00, 0x03, 0x02, 0x01, 0x01, 0x04, + 0x01, 0x00, 0x05, 0x01, 0x00, 0x06, 0x01, 0x00, 0x07, 0x06, 0x01, 0x02, + 0x77, 0x30, 0x00, 0x01, 0x0a, 0x0d, 0x01, 0x0b, 0x01, 0x01, 0x7f, 0x20, + 0x00, 0x10, 0x00, 0x21, 0x00, 0x0f, 0x0b, + ]) + ), + { + imports: { + import_0_v0: f0, + }, + } +); +let v107 = WebAssembly.promising(v104.exports.w0); +v107(); + +// CRASH INFO +// ========== +// TERMSIG: 11 +// STDERR: +// Received signal 11 SEGV_MAPERR 000000002011 +// STDOUT: +// +// FUZZER ARGS: .build/x86_64-unknown-linux-gnu/debug/FuzzilliCli --profile=v8 --engine=multi --storagePath=../storages/wasm_min_test_2 --jobs=48 --logLevel=verbose --resume /usr/local/google/home/cffsmith/v8/v8/out/fuzzbuild/d8 +// TARGET ARGS: /usr/local/google/home/cffsmith/v8/v8/out/fuzzbuild/d8 --expose-gc --omit-quit --allow-natives-syntax --fuzzing --jit-fuzzing --future --harmony --js-staging --wasm-staging --experimental-wasm-jspi +// CONTRIBUTORS: TypedArrayGenerator, ArrayGenerator, ObjectConstructorGenerator, CombineMutator, StringGenerator +// EXECUTION TIME: 227ms diff --git a/subject/js_engine/experiments/_tests/fuzzing_param_on/poc.js b/subject/js_engine/experiments/_tests/fuzzing_param_on/poc.js new file mode 100644 index 00000000..c2647e4f --- /dev/null +++ b/subject/js_engine/experiments/_tests/fuzzing_param_on/poc.js @@ -0,0 +1,92 @@ +// bughog_runtime_flags: --fuzzing --allow-natives-syntax --expose-gc --omit-quit --jit-fuzzing --future --harmony --js-staging --wasm-staging --experimental-wasm-jspi +// bughog_expected_output: Received signal 11 +%DebugPrint("bughog_sanity_check=ok"); + +function f0() { + // WasmModule Code: + // BeginWasmModule + // BeginWasmFunction [] ([] => .nothing) + // v7 <- EndWasmFunction + // v8 <- EndWasmModule + // + const v8 = new WebAssembly.Instance( + new WebAssembly.Module( + new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x60, + 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x04, 0x01, 0x00, 0x05, 0x01, 0x00, + 0x06, 0x01, 0x00, 0x07, 0x06, 0x01, 0x02, 0x77, 0x30, 0x00, 0x00, 0x0a, + 0x04, 0x01, 0x02, 0x00, 0x0b, + ]) + ) + ); + + let v11 = WebAssembly.promising(v8.exports.w0); + v11(f0, f0); + + console.log("A"); + + // WasmModule Code: + // BeginWasmModule + // BeginWasmFunction [v50, v51, v52, v53, v54] ([.wasmi32, .wasmf64, .wasmi32, .wasmf64, .wasmi32] => .wasmf32) + // v55 <- Constf32 '6.5286493' + // WasmReturn v55 + // v56 <- EndWasmFunction + // v57 <- EndWasmModule + // + const v57 = new WebAssembly.Instance( + new WebAssembly.Module( + new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x01, 0x60, + 0x05, 0x7f, 0x7c, 0x7f, 0x7c, 0x7f, 0x01, 0x7d, 0x03, 0x02, 0x01, 0x00, + 0x04, 0x01, 0x00, 0x05, 0x01, 0x00, 0x06, 0x01, 0x00, 0x07, 0x06, 0x01, + 0x02, 0x77, 0x30, 0x00, 0x00, 0x0a, 0x10, 0x01, 0x0e, 0x01, 0x01, 0x7d, + 0x43, 0xb2, 0xea, 0xd0, 0x40, 0x21, 0x05, 0x20, 0x05, 0x0f, 0x0b, + ]) + ) + ); + console.log("B"); + + // This triggers lazy compilation. + v57.exports.w0(); + console.log("C"); +} +// WasmModule Code: +// BeginWasmModule +// BeginWasmFunction [] ([] => .nothing) +// v102 <- WasmJsCall([] => .wasmi32) v0 [] +// WasmReturn +// v103 <- EndWasmFunction +// v104 <- EndWasmModule +// +const v104 = new WebAssembly.Instance( + new WebAssembly.Module( + new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x60, + 0x00, 0x01, 0x7f, 0x60, 0x00, 0x00, 0x02, 0x17, 0x01, 0x07, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x0b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x5f, 0x30, 0x5f, 0x76, 0x30, 0x00, 0x00, 0x03, 0x02, 0x01, 0x01, 0x04, + 0x01, 0x00, 0x05, 0x01, 0x00, 0x06, 0x01, 0x00, 0x07, 0x06, 0x01, 0x02, + 0x77, 0x30, 0x00, 0x01, 0x0a, 0x0d, 0x01, 0x0b, 0x01, 0x01, 0x7f, 0x20, + 0x00, 0x10, 0x00, 0x21, 0x00, 0x0f, 0x0b, + ]) + ), + { + imports: { + import_0_v0: f0, + }, + } +); +let v107 = WebAssembly.promising(v104.exports.w0); +v107(); + +// CRASH INFO +// ========== +// TERMSIG: 11 +// STDERR: +// Received signal 11 SEGV_MAPERR 000000002011 +// STDOUT: +// +// FUZZER ARGS: .build/x86_64-unknown-linux-gnu/debug/FuzzilliCli --profile=v8 --engine=multi --storagePath=../storages/wasm_min_test_2 --jobs=48 --logLevel=verbose --resume /usr/local/google/home/cffsmith/v8/v8/out/fuzzbuild/d8 +// TARGET ARGS: /usr/local/google/home/cffsmith/v8/v8/out/fuzzbuild/d8 --expose-gc --omit-quit --allow-natives-syntax --fuzzing --jit-fuzzing --future --harmony --js-staging --wasm-staging --experimental-wasm-jspi +// CONTRIBUTORS: TypedArrayGenerator, ArrayGenerator, ObjectConstructorGenerator, CombineMutator, StringGenerator +// EXECUTION TIME: 227ms diff --git a/subject/js_engine/experiments/_tests/fuzzing_param_on_print/poc.js b/subject/js_engine/experiments/_tests/fuzzing_param_on_print/poc.js new file mode 100644 index 00000000..c245b7a4 --- /dev/null +++ b/subject/js_engine/experiments/_tests/fuzzing_param_on_print/poc.js @@ -0,0 +1,92 @@ +// bughog_runtime_flags: --fuzzing --allow-natives-syntax --expose-gc --omit-quit --jit-fuzzing --future --harmony --js-staging --wasm-staging --experimental-wasm-jspi +// bughog_expected_output: Received signal 11 +print("bughog_sanity_check=ok"); + +function f0() { + // WasmModule Code: + // BeginWasmModule + // BeginWasmFunction [] ([] => .nothing) + // v7 <- EndWasmFunction + // v8 <- EndWasmModule + // + const v8 = new WebAssembly.Instance( + new WebAssembly.Module( + new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x60, + 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x04, 0x01, 0x00, 0x05, 0x01, 0x00, + 0x06, 0x01, 0x00, 0x07, 0x06, 0x01, 0x02, 0x77, 0x30, 0x00, 0x00, 0x0a, + 0x04, 0x01, 0x02, 0x00, 0x0b, + ]) + ) + ); + + let v11 = WebAssembly.promising(v8.exports.w0); + v11(f0, f0); + + console.log("A"); + + // WasmModule Code: + // BeginWasmModule + // BeginWasmFunction [v50, v51, v52, v53, v54] ([.wasmi32, .wasmf64, .wasmi32, .wasmf64, .wasmi32] => .wasmf32) + // v55 <- Constf32 '6.5286493' + // WasmReturn v55 + // v56 <- EndWasmFunction + // v57 <- EndWasmModule + // + const v57 = new WebAssembly.Instance( + new WebAssembly.Module( + new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x01, 0x60, + 0x05, 0x7f, 0x7c, 0x7f, 0x7c, 0x7f, 0x01, 0x7d, 0x03, 0x02, 0x01, 0x00, + 0x04, 0x01, 0x00, 0x05, 0x01, 0x00, 0x06, 0x01, 0x00, 0x07, 0x06, 0x01, + 0x02, 0x77, 0x30, 0x00, 0x00, 0x0a, 0x10, 0x01, 0x0e, 0x01, 0x01, 0x7d, + 0x43, 0xb2, 0xea, 0xd0, 0x40, 0x21, 0x05, 0x20, 0x05, 0x0f, 0x0b, + ]) + ) + ); + console.log("B"); + + // This triggers lazy compilation. + v57.exports.w0(); + console.log("C"); +} +// WasmModule Code: +// BeginWasmModule +// BeginWasmFunction [] ([] => .nothing) +// v102 <- WasmJsCall([] => .wasmi32) v0 [] +// WasmReturn +// v103 <- EndWasmFunction +// v104 <- EndWasmModule +// +const v104 = new WebAssembly.Instance( + new WebAssembly.Module( + new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x60, + 0x00, 0x01, 0x7f, 0x60, 0x00, 0x00, 0x02, 0x17, 0x01, 0x07, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x0b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x5f, 0x30, 0x5f, 0x76, 0x30, 0x00, 0x00, 0x03, 0x02, 0x01, 0x01, 0x04, + 0x01, 0x00, 0x05, 0x01, 0x00, 0x06, 0x01, 0x00, 0x07, 0x06, 0x01, 0x02, + 0x77, 0x30, 0x00, 0x01, 0x0a, 0x0d, 0x01, 0x0b, 0x01, 0x01, 0x7f, 0x20, + 0x00, 0x10, 0x00, 0x21, 0x00, 0x0f, 0x0b, + ]) + ), + { + imports: { + import_0_v0: f0, + }, + } +); +let v107 = WebAssembly.promising(v104.exports.w0); +v107(); + +// CRASH INFO +// ========== +// TERMSIG: 11 +// STDERR: +// Received signal 11 SEGV_MAPERR 000000002011 +// STDOUT: +// +// FUZZER ARGS: .build/x86_64-unknown-linux-gnu/debug/FuzzilliCli --profile=v8 --engine=multi --storagePath=../storages/wasm_min_test_2 --jobs=48 --logLevel=verbose --resume /usr/local/google/home/cffsmith/v8/v8/out/fuzzbuild/d8 +// TARGET ARGS: /usr/local/google/home/cffsmith/v8/v8/out/fuzzbuild/d8 --expose-gc --omit-quit --allow-natives-syntax --fuzzing --jit-fuzzing --future --harmony --js-staging --wasm-staging --experimental-wasm-jspi +// CONTRIBUTORS: TypedArrayGenerator, ArrayGenerator, ObjectConstructorGenerator, CombineMutator, StringGenerator +// EXECUTION TIME: 227ms diff --git a/subject/js_engine/experiments/_tests/sanbox_testing/poc.js b/subject/js_engine/experiments/_tests/sanbox_testing/poc.js new file mode 100644 index 00000000..165a3248 --- /dev/null +++ b/subject/js_engine/experiments/_tests/sanbox_testing/poc.js @@ -0,0 +1,17 @@ +// bughog_runtime_flags: --allow-natives-syntax --sandbox-testing +// bughog_expected_output: AddressSanitizer + +print('bughog_sanity_check=ok'); + +// Agnostic V8 Sandbox Escape Target Selection +let targetAddress; +if (typeof Sandbox === 'object' && 'targetPage' in Sandbox) { + // OLD MODE: V8 requires writing to this specific page to prove escape + targetAddress = Sandbox.targetPage; + console.log("[+] Detected legacy Sandbox testing API. Target:", targetAddress); +} else { + // NEW MODE: Any OOB write causes a crash caught by the sandbox filter + // 0x41414141 is a safe bet for an unmapped address outside the 1TB sandbox + targetAddress = 0x41414141n; + console.log("[+] Detected modern crash-based verification. Target:", targetAddress); +} \ No newline at end of file diff --git a/subject/js_engine/experiments/_tests/sandbox_modern/poc.js b/subject/js_engine/experiments/_tests/sandbox_modern/poc.js new file mode 100644 index 00000000..ce20fabb --- /dev/null +++ b/subject/js_engine/experiments/_tests/sandbox_modern/poc.js @@ -0,0 +1,17 @@ +// bughog_runtime_flags: --allow-natives-syntax --sandbox-testing +// bughog_expected_output: ^\[\+\] Detected modern crash-based verification. + +print('bughog_sanity_check=ok'); + +// Agnostic V8 Sandbox Escape Target Selection +let targetAddress; +if (typeof Sandbox === 'object' && 'targetPage' in Sandbox) { + // OLD MODE: V8 requires writing to this specific page to prove escape + targetAddress = Sandbox.targetPage; + console.log("[+] Detected legacy Sandbox testing API. Target:", targetAddress); +} else { + // NEW MODE: Any OOB write causes a crash caught by the sandbox filter + // 0x41414141 is a safe bet for an unmapped address outside the 1TB sandbox + targetAddress = 0x41414141n; + console.log("[+] Detected modern crash-based verification. Target:", targetAddress); +} \ No newline at end of file diff --git a/subject/js_engine/experiments/_tests/sandbox_targetpage/poc.js b/subject/js_engine/experiments/_tests/sandbox_targetpage/poc.js new file mode 100644 index 00000000..16561b95 --- /dev/null +++ b/subject/js_engine/experiments/_tests/sandbox_targetpage/poc.js @@ -0,0 +1,17 @@ +// bughog_runtime_flags: --allow-natives-syntax --sandbox-testing +// bughog_expected_output: \[\+\] Detected legacy Sandbox testing API. + +print('bughog_sanity_check=ok'); + +// Agnostic V8 Sandbox Escape Target Selection +let targetAddress; +if (typeof Sandbox === 'object' && 'targetPage' in Sandbox) { + // OLD MODE: V8 requires writing to this specific page to prove escape + targetAddress = Sandbox.targetPage; + console.log("[+] Detected legacy Sandbox testing API. Target:", targetAddress); +} else { + // NEW MODE: Any OOB write causes a crash caught by the sandbox filter + // 0x41414141 is a safe bet for an unmapped address outside the 1TB sandbox + targetAddress = 0x41414141n; + console.log("[+] Detected modern crash-based verification. Target:", targetAddress); +} \ No newline at end of file