diff --git a/android_webview/js_sandbox/service/js_sandbox_message_port.cc b/android_webview/js_sandbox/service/js_sandbox_message_port.cc --- a/android_webview/js_sandbox/service/js_sandbox_message_port.cc +++ b/android_webview/js_sandbox/service/js_sandbox_message_port.cc @@ -16,6 +16,7 @@ #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/location.h" +#include "base/threading/platform_thread.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/task/single_thread_task_runner.h" @@ -192,6 +193,14 @@ void JsSandboxMessagePort::Close() { } bool JsSandboxMessagePort::TryAllocateMemoryBudget(JNIEnv* env, int64_t size) { + // POC: widen the race window. This method runs on a Binder thread with no + // synchronisation against JsSandboxIsolate::DeleteSelf(). At this point + // |this| (cppgc-allocated) and |js_sandbox_isolate_| are both still live, + // but the isolate thread can free them at any moment. Sleeping here makes + // the UAF deterministic: close the isolate from Java while a message is + // in flight and the dereference of |js_sandbox_isolate_| below lands on + // freed memory. + base::PlatformThread::Sleep(base::Milliseconds(500)); CHECK_GE(size, 0); if (base::as_unsigned(size) > SIZE_MAX) { return false;