Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Side by Side Diff: extensions/browser/extension_function_dispatcher.cc

Issue 2629783002: Upload crash reports when ExtensionFunctions generate bad messages. (Closed)
Patch Set: sync Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « extensions/browser/bad_message.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/extension_function_dispatcher.h" 5 #include "extensions/browser/extension_function_dispatcher.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/json/json_string_value_serializer.h" 10 #include "base/json/json_string_value_serializer.h"
(...skipping 13 matching lines...) Expand all
24 #include "content/public/browser/render_frame_host.h" 24 #include "content/public/browser/render_frame_host.h"
25 #include "content/public/browser/render_process_host.h" 25 #include "content/public/browser/render_process_host.h"
26 #include "content/public/browser/render_process_host_observer.h" 26 #include "content/public/browser/render_process_host_observer.h"
27 #include "content/public/browser/render_view_host.h" 27 #include "content/public/browser/render_view_host.h"
28 #include "content/public/browser/service_worker_context.h" 28 #include "content/public/browser/service_worker_context.h"
29 #include "content/public/browser/user_metrics.h" 29 #include "content/public/browser/user_metrics.h"
30 #include "content/public/browser/web_contents.h" 30 #include "content/public/browser/web_contents.h"
31 #include "content/public/browser/web_contents_observer.h" 31 #include "content/public/browser/web_contents_observer.h"
32 #include "content/public/common/result_codes.h" 32 #include "content/public/common/result_codes.h"
33 #include "extensions/browser/api_activity_monitor.h" 33 #include "extensions/browser/api_activity_monitor.h"
34 #include "extensions/browser/bad_message.h"
34 #include "extensions/browser/extension_function_registry.h" 35 #include "extensions/browser/extension_function_registry.h"
35 #include "extensions/browser/extension_registry.h" 36 #include "extensions/browser/extension_registry.h"
36 #include "extensions/browser/extension_system.h" 37 #include "extensions/browser/extension_system.h"
37 #include "extensions/browser/extension_util.h" 38 #include "extensions/browser/extension_util.h"
38 #include "extensions/browser/extensions_browser_client.h" 39 #include "extensions/browser/extensions_browser_client.h"
39 #include "extensions/browser/io_thread_extension_message_filter.h" 40 #include "extensions/browser/io_thread_extension_message_filter.h"
40 #include "extensions/browser/process_manager.h" 41 #include "extensions/browser/process_manager.h"
41 #include "extensions/browser/process_map.h" 42 #include "extensions/browser/process_map.h"
42 #include "extensions/browser/quota_service.h" 43 #include "extensions/browser/quota_service.h"
43 #include "extensions/common/constants.h" 44 #include "extensions/common/constants.h"
(...skipping 28 matching lines...) Expand all
72 73
73 // Separate copy of ExtensionAPI used for IO thread extension functions. We need 74 // Separate copy of ExtensionAPI used for IO thread extension functions. We need
74 // this because ExtensionAPI has mutable data. It should be possible to remove 75 // this because ExtensionAPI has mutable data. It should be possible to remove
75 // this once all the extension APIs are updated to the feature system. 76 // this once all the extension APIs are updated to the feature system.
76 struct Static { 77 struct Static {
77 Static() : api(ExtensionAPI::CreateWithDefaultConfiguration()) {} 78 Static() : api(ExtensionAPI::CreateWithDefaultConfiguration()) {}
78 std::unique_ptr<ExtensionAPI> api; 79 std::unique_ptr<ExtensionAPI> api;
79 }; 80 };
80 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER; 81 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER;
81 82
82 // Kills the specified process because it sends us a malformed message. 83 void LogBadMessage(functions::HistogramValue histogram_value) {
83 // Track the specific function's |histogram_value|, as this may indicate a bug 84 content::RecordAction(base::UserMetricsAction("BadMessageTerminate_EFD"));
84 // in that API's implementation on the renderer. 85 // Track the specific function's |histogram_value|, as this may indicate a
85 void KillBadMessageSender(const base::Process& process, 86 // bug in that API's implementation.
86 functions::HistogramValue histogram_value) { 87 UMA_HISTOGRAM_ENUMERATION("Extensions.BadMessageFunctionName",
88 histogram_value, functions::ENUM_BOUNDARY);
89 }
90
91 template <class T>
92 void ReceivedBadMessage(T* bad_message_sender,
93 bad_message::BadMessageReason reason,
94 functions::HistogramValue histogram_value) {
95 LogBadMessage(histogram_value);
87 // The renderer has done validation before sending extension api requests. 96 // The renderer has done validation before sending extension api requests.
88 // Therefore, we should never receive a request that is invalid in a way 97 // Therefore, we should never receive a request that is invalid in a way
89 // that JSON validation in the renderer should have caught. It could be an 98 // that JSON validation in the renderer should have caught. It could be an
90 // attacker trying to exploit the browser, so we crash the renderer instead. 99 // attacker trying to exploit the browser, so we crash the renderer instead.
91 LOG(ERROR) << "Terminating renderer because of malformed extension message."; 100 bad_message::ReceivedBadMessage(bad_message_sender, reason);
92 if (content::RenderProcessHost::run_renderer_in_process()) {
93 // In single process mode it is better if we don't suicide but just crash.
94 CHECK(false);
95 return;
96 }
97
98 NOTREACHED();
99 content::RecordAction(base::UserMetricsAction("BadMessageTerminate_EFD"));
100 UMA_HISTOGRAM_ENUMERATION("Extensions.BadMessageFunctionName",
101 histogram_value, functions::ENUM_BOUNDARY);
102 if (process.IsValid())
103 process.Terminate(content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
104 } 101 }
105 102
106 void KillBadMessageSenderRPH(content::RenderProcessHost* sender_process_host, 103 template <class T>
107 functions::HistogramValue histogram_value) {
108 base::Process peer_process =
109 content::RenderProcessHost::run_renderer_in_process()
110 ? base::Process::Current()
111 : base::Process::DeprecatedGetProcessFromHandle(
112 sender_process_host->GetHandle());
113 KillBadMessageSender(peer_process, histogram_value);
114 }
115
116 void CommonResponseCallback(IPC::Sender* ipc_sender, 104 void CommonResponseCallback(IPC::Sender* ipc_sender,
117 int routing_id, 105 int routing_id,
118 const base::Process& peer_process, 106 T* bad_message_sender,
119 int request_id, 107 int request_id,
120 ExtensionFunction::ResponseType type, 108 ExtensionFunction::ResponseType type,
121 const base::ListValue& results, 109 const base::ListValue& results,
122 const std::string& error, 110 const std::string& error,
123 functions::HistogramValue histogram_value) { 111 functions::HistogramValue histogram_value) {
124 DCHECK(ipc_sender); 112 DCHECK(ipc_sender);
125 113
126 if (type == ExtensionFunction::BAD_MESSAGE) { 114 if (type == ExtensionFunction::BAD_MESSAGE) {
127 KillBadMessageSender(peer_process, histogram_value); 115 ReceivedBadMessage(bad_message_sender, bad_message::EFD_BAD_MESSAGE,
116 histogram_value);
128 return; 117 return;
129 } 118 }
130 119
131 ipc_sender->Send(new ExtensionMsg_Response( 120 ipc_sender->Send(new ExtensionMsg_Response(
132 routing_id, request_id, type == ExtensionFunction::SUCCEEDED, results, 121 routing_id, request_id, type == ExtensionFunction::SUCCEEDED, results,
133 error)); 122 error));
134 } 123 }
135 124
136 void IOThreadResponseCallback( 125 void IOThreadResponseCallback(
137 const base::WeakPtr<IOThreadExtensionMessageFilter>& ipc_sender, 126 const base::WeakPtr<IOThreadExtensionMessageFilter>& ipc_sender,
138 int routing_id, 127 int routing_id,
139 int request_id, 128 int request_id,
140 ExtensionFunction::ResponseType type, 129 ExtensionFunction::ResponseType type,
141 const base::ListValue& results, 130 const base::ListValue& results,
142 const std::string& error, 131 const std::string& error,
143 functions::HistogramValue histogram_value) { 132 functions::HistogramValue histogram_value) {
144 if (!ipc_sender.get()) 133 if (!ipc_sender.get())
145 return; 134 return;
146 135
147 base::Process peer_process = 136 CommonResponseCallback(ipc_sender.get(), routing_id, ipc_sender.get(),
148 base::Process::DeprecatedGetProcessFromHandle(ipc_sender->PeerHandle()); 137 request_id, type, results, error, histogram_value);
149 CommonResponseCallback(ipc_sender.get(), routing_id, peer_process, request_id,
150 type, results, error, histogram_value);
151 } 138 }
152 139
153 } // namespace 140 } // namespace
154 141
155 class ExtensionFunctionDispatcher::UIThreadResponseCallbackWrapper 142 class ExtensionFunctionDispatcher::UIThreadResponseCallbackWrapper
156 : public content::WebContentsObserver { 143 : public content::WebContentsObserver {
157 public: 144 public:
158 UIThreadResponseCallbackWrapper( 145 UIThreadResponseCallbackWrapper(
159 const base::WeakPtr<ExtensionFunctionDispatcher>& dispatcher, 146 const base::WeakPtr<ExtensionFunctionDispatcher>& dispatcher,
160 content::RenderFrameHost* render_frame_host) 147 content::RenderFrameHost* render_frame_host)
(...skipping 27 matching lines...) Expand all
188 weak_ptr_factory_.GetWeakPtr(), 175 weak_ptr_factory_.GetWeakPtr(),
189 request_id); 176 request_id);
190 } 177 }
191 178
192 private: 179 private:
193 void OnExtensionFunctionCompleted(int request_id, 180 void OnExtensionFunctionCompleted(int request_id,
194 ExtensionFunction::ResponseType type, 181 ExtensionFunction::ResponseType type,
195 const base::ListValue& results, 182 const base::ListValue& results,
196 const std::string& error, 183 const std::string& error,
197 functions::HistogramValue histogram_value) { 184 functions::HistogramValue histogram_value) {
198 base::Process process =
199 content::RenderProcessHost::run_renderer_in_process()
200 ? base::Process::Current()
201 : base::Process::DeprecatedGetProcessFromHandle(
202 render_frame_host_->GetProcess()->GetHandle());
203 CommonResponseCallback(render_frame_host_, 185 CommonResponseCallback(render_frame_host_,
204 render_frame_host_->GetRoutingID(), 186 render_frame_host_->GetRoutingID(),
205 process, request_id, type, results, error, 187 render_frame_host_->GetProcess(), request_id, type,
206 histogram_value); 188 results, error, histogram_value);
207 } 189 }
208 190
209 base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_; 191 base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_;
210 content::RenderFrameHost* render_frame_host_; 192 content::RenderFrameHost* render_frame_host_;
211 base::WeakPtrFactory<UIThreadResponseCallbackWrapper> weak_ptr_factory_; 193 base::WeakPtrFactory<UIThreadResponseCallbackWrapper> weak_ptr_factory_;
212 194
213 DISALLOW_COPY_AND_ASSIGN(UIThreadResponseCallbackWrapper); 195 DISALLOW_COPY_AND_ASSIGN(UIThreadResponseCallbackWrapper);
214 }; 196 };
215 197
216 class ExtensionFunctionDispatcher::UIThreadWorkerResponseCallbackWrapper 198 class ExtensionFunctionDispatcher::UIThreadWorkerResponseCallbackWrapper
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 } 241 }
260 242
261 void OnExtensionFunctionCompleted(int request_id, 243 void OnExtensionFunctionCompleted(int request_id,
262 ExtensionFunction::ResponseType type, 244 ExtensionFunction::ResponseType type,
263 const base::ListValue& results, 245 const base::ListValue& results,
264 const std::string& error, 246 const std::string& error,
265 functions::HistogramValue histogram_value) { 247 functions::HistogramValue histogram_value) {
266 content::RenderProcessHost* sender = 248 content::RenderProcessHost* sender =
267 content::RenderProcessHost::FromID(render_process_id_); 249 content::RenderProcessHost::FromID(render_process_id_);
268 if (type == ExtensionFunction::BAD_MESSAGE) { 250 if (type == ExtensionFunction::BAD_MESSAGE) {
269 KillBadMessageSenderRPH(sender, histogram_value); 251 ReceivedBadMessage(sender, bad_message::EFD_BAD_MESSAGE_WORKER,
252 histogram_value);
270 return; 253 return;
271 } 254 }
272 DCHECK(sender); 255 DCHECK(sender);
273 sender->Send(new ExtensionMsg_ResponseWorker( 256 sender->Send(new ExtensionMsg_ResponseWorker(
274 worker_thread_id_, request_id, type == ExtensionFunction::SUCCEEDED, 257 worker_thread_id_, request_id, type == ExtensionFunction::SUCCEEDED,
275 results, error)); 258 results, error));
276 } 259 }
277 260
278 base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_; 261 base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_;
279 ScopedObserver<content::RenderProcessHost, 262 ScopedObserver<content::RenderProcessHost,
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 // static 633 // static
651 void ExtensionFunctionDispatcher::SendAccessDenied( 634 void ExtensionFunctionDispatcher::SendAccessDenied(
652 const ExtensionFunction::ResponseCallback& callback, 635 const ExtensionFunction::ResponseCallback& callback,
653 functions::HistogramValue histogram_value) { 636 functions::HistogramValue histogram_value) {
654 base::ListValue empty_list; 637 base::ListValue empty_list;
655 callback.Run(ExtensionFunction::FAILED, empty_list, 638 callback.Run(ExtensionFunction::FAILED, empty_list,
656 "Access to extension API denied.", histogram_value); 639 "Access to extension API denied.", histogram_value);
657 } 640 }
658 641
659 } // namespace extensions 642 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/bad_message.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698