Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: avoid contextBridge crash when RenderFrame address is reused #21501

Merged
merged 2 commits into from Dec 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 3 additions & 11 deletions shell/renderer/api/atom_api_context_bridge.cc
Expand Up @@ -47,20 +47,12 @@ content::RenderFrame* GetRenderFrame(const v8::Local<v8::Object>& value) {
return content::RenderFrame::FromWebFrame(frame);
}

std::map<content::RenderFrame*, context_bridge::RenderFramePersistenceStore*>&
GetStoreMap() {
static base::NoDestructor<std::map<
content::RenderFrame*, context_bridge::RenderFramePersistenceStore*>>
store_map;
return *store_map;
}

context_bridge::RenderFramePersistenceStore* GetOrCreateStore(
content::RenderFrame* render_frame) {
auto it = GetStoreMap().find(render_frame);
if (it == GetStoreMap().end()) {
auto it = context_bridge::GetStoreMap().find(render_frame->GetRoutingID());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will there be a possibility of cross process access to this function ? GetRoutingID is not unique across processes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@deepak1556 No, the bridge operates across two contexts in the same process

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for confirming.

if (it == context_bridge::GetStoreMap().end()) {
auto* store = new context_bridge::RenderFramePersistenceStore(render_frame);
GetStoreMap().emplace(render_frame, store);
context_bridge::GetStoreMap().emplace(render_frame->GetRoutingID(), store);
return store;
}
return it->second;
Expand Down
Expand Up @@ -66,6 +66,12 @@ class CachedProxyLifeMonitor final : public ObjectLifeMonitor {

} // namespace

std::map<int32_t, RenderFramePersistenceStore*>& GetStoreMap() {
static base::NoDestructor<std::map<int32_t, RenderFramePersistenceStore*>>
store_map;
return *store_map;
}

WeakGlobalPairNode::WeakGlobalPairNode(WeakGlobalPair pair) {
this->pair = std::move(pair);
}
Expand All @@ -78,11 +84,13 @@ WeakGlobalPairNode::~WeakGlobalPairNode() {

RenderFramePersistenceStore::RenderFramePersistenceStore(
content::RenderFrame* render_frame)
: content::RenderFrameObserver(render_frame) {}
: content::RenderFrameObserver(render_frame),
routing_id_(render_frame->GetRoutingID()) {}

RenderFramePersistenceStore::~RenderFramePersistenceStore() = default;

void RenderFramePersistenceStore::OnDestruct() {
GetStoreMap().erase(routing_id_);
delete this;
}

Expand Down
Expand Up @@ -58,11 +58,15 @@ class RenderFramePersistenceStore final : public content::RenderFrameObserver {
// proxy maps are weak globals, i.e. these are not retained beyond
// there normal JS lifetime. You must check IsEmpty()

const int32_t routing_id_;

// object_identity ==> [from_value, proxy_value]
std::map<int, WeakGlobalPairNode*> proxy_map_;
base::WeakPtrFactory<RenderFramePersistenceStore> weak_factory_{this};
};

std::map<int32_t, RenderFramePersistenceStore*>& GetStoreMap();

} // namespace context_bridge

} // namespace api
Expand Down