From 512209215ce9dd0e67a4b9012f7c8cdea44c0f7a Mon Sep 17 00:00:00 2001 From: Tomislav Novak Date: Fri, 22 Mar 2024 09:15:08 -0700 Subject: [PATCH] Fix use-after-free in AsyncEventBeat Summary: Both common and Android implementations of AsyncEventBeat use weak_ptrs to determine if the object is still valid before invoking the callback. Move the write to `isBeatCallbackScheduled_` down so it's protected by that same check. Changelog: [Internal] Reviewed By: javache, NickGerleman Differential Revision: D55226529 --- .../ReactAndroid/src/main/jni/react/fabric/AsyncEventBeat.cpp | 2 +- .../react/renderer/scheduler/AsynchronousEventBeat.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AsyncEventBeat.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AsyncEventBeat.cpp index 62eab4858fbe..4160e35da17d 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AsyncEventBeat.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AsyncEventBeat.cpp @@ -38,12 +38,12 @@ void AsyncEventBeat::tick() const { isBeatCallbackScheduled_ = true; runtimeExecutor_([this, ownerBox = ownerBox_](jsi::Runtime& runtime) { - isBeatCallbackScheduled_ = false; auto owner = ownerBox->owner.lock(); if (!owner) { return; } + isBeatCallbackScheduled_ = false; if (beatCallback_) { beatCallback_(runtime); } diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp index 692aaa867d27..30ab47eea424 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp @@ -43,13 +43,12 @@ void AsynchronousEventBeat::induce() const { isBeatCallbackScheduled_ = true; runtimeExecutor_([this, weakOwner](jsi::Runtime& runtime) { - isBeatCallbackScheduled_ = false; - auto owner = weakOwner.lock(); if (!owner) { return; } + isBeatCallbackScheduled_ = false; if (beatCallback_) { beatCallback_(runtime); }