From fe4ac695600b023774e67c2ec9eebbbd055ad1be Mon Sep 17 00:00:00 2001 From: etkmao Date: Wed, 18 Sep 2024 18:07:36 +0800 Subject: [PATCH 1/2] fix(core): add safe static var for ios static crash --- dom/src/dom/taitank_layout_node.cc | 15 ++++++---- driver/js/src/napi/jsc/jsc_ctx.cc | 20 ++++++++----- modules/footstone/include/footstone/check.h | 31 +++++++++++++++++++++ 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/dom/src/dom/taitank_layout_node.cc b/dom/src/dom/taitank_layout_node.cc index cd9f1766fcd..ae1a02c9d48 100644 --- a/dom/src/dom/taitank_layout_node.cc +++ b/dom/src/dom/taitank_layout_node.cc @@ -22,7 +22,7 @@ #include #include - +#include "footstone/check.h" #include "footstone/logging.h" #include "dom/node_props.h" @@ -98,12 +98,13 @@ class TaitankLayoutConsts { {"inherit", DIRECTION_INHERIT}, {"ltr", DIRECTION_LTR}, {"rtl", DIRECTION_RTL}}; }; -static std::shared_ptr global_layout_consts = nullptr; +static footstone::SafeStaticVar global_layout_consts; #define TAITANK_GET_STYLE_DECL(NAME, TYPE, DEFAULT) \ static TYPE GetStyle##NAME(const std::string& key) { \ - if (global_layout_consts == nullptr) return DEFAULT; \ - auto &map = global_layout_consts->k##NAME##Map; \ + auto layout_consts = footstone::GetSafeStaticVar(&global_layout_consts); \ + if (layout_consts == nullptr) return DEFAULT; \ + auto &map = layout_consts->k##NAME##Map; \ auto iter = map.find(key); \ if (iter != map.end()) return iter->second; \ return DEFAULT; \ @@ -822,8 +823,10 @@ void TaitankLayoutNode::Deallocate() { } void InitLayoutConsts() { - if (global_layout_consts == nullptr) { - global_layout_consts = std::make_shared(); + auto layout_consts = footstone::GetSafeStaticVar(&global_layout_consts); + if (layout_consts == nullptr) { + layout_consts = std::make_shared(); + footstone::InitSafeStaticVar(&global_layout_consts, layout_consts); } } diff --git a/driver/js/src/napi/jsc/jsc_ctx.cc b/driver/js/src/napi/jsc/jsc_ctx.cc index 51152479073..18fcc4b09a3 100644 --- a/driver/js/src/napi/jsc/jsc_ctx.cc +++ b/driver/js/src/napi/jsc/jsc_ctx.cc @@ -21,6 +21,7 @@ */ #include "driver/napi/jsc/jsc_ctx.h" +#include "footstone/check.h" #include "footstone/logging.h" #include "footstone/string_view_utils.h" #include "driver/napi/jsc/jsc_ctx_value.h" @@ -49,13 +50,15 @@ constexpr char16_t kSetStr[] = u"set"; static std::once_flag global_class_flag; static JSClassRef global_class; -static std::shared_ptr global_constructor_data_mgr = nullptr; +static footstone::SafeStaticVar global_constructor_data_mgr; JSCCtx::JSCCtx(JSContextGroupRef group, std::weak_ptr vm): vm_(vm) { std::call_once(global_class_flag, []() { JSClassDefinition global = kJSClassDefinitionEmpty; global_class = JSClassCreate(&global); - global_constructor_data_mgr = std::make_shared(); + + auto constructor_data_mgr = std::make_shared(); + footstone::InitSafeStaticVar(&global_constructor_data_mgr, constructor_data_mgr); }); context_ = JSGlobalContextCreateInGroup(group, global_class); @@ -69,8 +72,9 @@ JSCCtx::~JSCCtx() { JSGlobalContextRelease(context_); for (auto& [key, item] : constructor_data_holder_) { item->prototype = nullptr; - if (global_constructor_data_mgr) { - global_constructor_data_mgr->ClearConstructorDataPtr(item.get()); + auto constructor_data_mgr = footstone::GetSafeStaticVar(&global_constructor_data_mgr); + if (constructor_data_mgr) { + constructor_data_mgr->ClearConstructorDataPtr(item.get()); } } } @@ -264,7 +268,8 @@ std::shared_ptr JSCCtx::DefineClass(const string_view& name, if (!private_data) { return; } - if (!global_constructor_data_mgr || !global_constructor_data_mgr->IsValidConstructorDataPtr(private_data)) { + auto constructor_data_mgr = footstone::GetSafeStaticVar(&global_constructor_data_mgr); + if (!constructor_data_mgr || !constructor_data_mgr->IsValidConstructorDataPtr(private_data)) { return; } auto constructor_data = reinterpret_cast(private_data); @@ -969,8 +974,9 @@ void* JSCCtx::GetPrivateData(const std::shared_ptr& object) { } void JSCCtx::SaveConstructorData(std::unique_ptr constructor_data) { - if (global_constructor_data_mgr) { - global_constructor_data_mgr->SaveConstructorDataPtr(constructor_data.get()); + auto constructor_data_mgr = footstone::GetSafeStaticVar(&global_constructor_data_mgr); + if (constructor_data_mgr) { + constructor_data_mgr->SaveConstructorDataPtr(constructor_data.get()); } constructor_data_holder_[constructor_data->class_ref] = std::move(constructor_data); } diff --git a/modules/footstone/include/footstone/check.h b/modules/footstone/include/footstone/check.h index ee610fc4b33..0f9bb8b2457 100644 --- a/modules/footstone/include/footstone/check.h +++ b/modules/footstone/include/footstone/check.h @@ -44,5 +44,36 @@ static constexpr TargetType checked_numeric_cast(const SourceType& source) { return target; } +template +class SafeStaticVar { +public: + uint64_t sign_before_; + std::shared_ptr var_inner_; + uint64_t sign_after_; +}; + +template +static void InitSafeStaticVar(SafeStaticVar *var, std::shared_ptr &var_inner) { + var->var_inner_ = var_inner; + uint64_t *p = (uint64_t *)&var_inner; + uint64_t value = *p; + var->sign_before_ = value; + var->sign_after_ = value; +} + +template +static std::shared_ptr GetSafeStaticVar(SafeStaticVar *var) { + uint64_t *p = (uint64_t *)&var->var_inner_; + uint64_t value = *p; + if (var->sign_before_ != value) { + return nullptr; + } + if (var->sign_after_ != value) { + return nullptr; + } + return var->var_inner_; +} + + } } From 8c8691ea660bd1d89212effa131d1becd2fa17ab Mon Sep 17 00:00:00 2001 From: etkmao Date: Thu, 26 Sep 2024 17:45:11 +0800 Subject: [PATCH 2/2] fix(core): add safe static var for ios static crash --- modules/footstone/include/footstone/check.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/footstone/include/footstone/check.h b/modules/footstone/include/footstone/check.h index 0f9bb8b2457..234e747a83a 100644 --- a/modules/footstone/include/footstone/check.h +++ b/modules/footstone/include/footstone/check.h @@ -55,8 +55,9 @@ class SafeStaticVar { template static void InitSafeStaticVar(SafeStaticVar *var, std::shared_ptr &var_inner) { var->var_inner_ = var_inner; - uint64_t *p = (uint64_t *)&var_inner; + uint64_t *p = (uint64_t *)&var->var_inner_; uint64_t value = *p; + value ^= 0xf; var->sign_before_ = value; var->sign_after_ = value; } @@ -65,6 +66,10 @@ template static std::shared_ptr GetSafeStaticVar(SafeStaticVar *var) { uint64_t *p = (uint64_t *)&var->var_inner_; uint64_t value = *p; + if (value == 0) { + return nullptr; + } + value ^= 0xf; if (var->sign_before_ != value) { return nullptr; }