OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 // in that API's implementation on the renderer. | |
85 void KillBadMessageSender(const base::Process& process, | |
86 functions::HistogramValue histogram_value) { | |
87 // The renderer has done validation before sending extension api requests. | |
88 // 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 | |
90 // attacker trying to exploit the browser, so we crash the renderer instead. | |
Charlie Reis
2017/01/13 21:22:25
Is there somewhere you can preserve this comment?
lazyboy
2017/01/14 01:04:43
Restored the comment.
| |
91 LOG(ERROR) << "Terminating renderer because of malformed extension message."; | |
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")); | 84 content::RecordAction(base::UserMetricsAction("BadMessageTerminate_EFD")); |
85 // Track the specific function's |histogram_value|, as this may indicate a | |
86 // bug in that API's implementation. | |
100 UMA_HISTOGRAM_ENUMERATION("Extensions.BadMessageFunctionName", | 87 UMA_HISTOGRAM_ENUMERATION("Extensions.BadMessageFunctionName", |
101 histogram_value, functions::ENUM_BOUNDARY); | 88 histogram_value, functions::ENUM_BOUNDARY); |
102 if (process.IsValid()) | |
103 process.Terminate(content::RESULT_CODE_KILLED_BAD_MESSAGE, false); | |
104 } | 89 } |
105 | 90 |
106 void KillBadMessageSenderRPH(content::RenderProcessHost* sender_process_host, | 91 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, | 92 void CommonResponseCallback(IPC::Sender* ipc_sender, |
117 int routing_id, | 93 int routing_id, |
118 const base::Process& peer_process, | 94 T bad_message_sender, |
Devlin
2017/01/13 16:16:17
nitty nit: Let's use T* (so that T is RenderProces
lazyboy
2017/01/14 01:04:43
Done.
| |
119 int request_id, | 95 int request_id, |
120 ExtensionFunction::ResponseType type, | 96 ExtensionFunction::ResponseType type, |
121 const base::ListValue& results, | 97 const base::ListValue& results, |
122 const std::string& error, | 98 const std::string& error, |
123 functions::HistogramValue histogram_value) { | 99 functions::HistogramValue histogram_value) { |
124 DCHECK(ipc_sender); | 100 DCHECK(ipc_sender); |
125 | 101 |
126 if (type == ExtensionFunction::BAD_MESSAGE) { | 102 if (type == ExtensionFunction::BAD_MESSAGE) { |
127 KillBadMessageSender(peer_process, histogram_value); | 103 LogBadMessage(histogram_value); |
104 bad_message::ReceivedBadMessage(bad_message_sender, | |
105 bad_message::EFD_BAD_MESSAGE); | |
128 return; | 106 return; |
129 } | 107 } |
130 | 108 |
131 ipc_sender->Send(new ExtensionMsg_Response( | 109 ipc_sender->Send(new ExtensionMsg_Response( |
132 routing_id, request_id, type == ExtensionFunction::SUCCEEDED, results, | 110 routing_id, request_id, type == ExtensionFunction::SUCCEEDED, results, |
133 error)); | 111 error)); |
134 } | 112 } |
135 | 113 |
136 void IOThreadResponseCallback( | 114 void IOThreadResponseCallback( |
137 const base::WeakPtr<IOThreadExtensionMessageFilter>& ipc_sender, | 115 const base::WeakPtr<IOThreadExtensionMessageFilter>& ipc_sender, |
138 int routing_id, | 116 int routing_id, |
139 int request_id, | 117 int request_id, |
140 ExtensionFunction::ResponseType type, | 118 ExtensionFunction::ResponseType type, |
141 const base::ListValue& results, | 119 const base::ListValue& results, |
142 const std::string& error, | 120 const std::string& error, |
143 functions::HistogramValue histogram_value) { | 121 functions::HistogramValue histogram_value) { |
144 if (!ipc_sender.get()) | 122 if (!ipc_sender.get()) |
145 return; | 123 return; |
146 | 124 |
147 base::Process peer_process = | 125 CommonResponseCallback(ipc_sender.get(), routing_id, ipc_sender.get(), |
148 base::Process::DeprecatedGetProcessFromHandle(ipc_sender->PeerHandle()); | 126 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 } | 127 } |
152 | 128 |
153 } // namespace | 129 } // namespace |
154 | 130 |
155 class ExtensionFunctionDispatcher::UIThreadResponseCallbackWrapper | 131 class ExtensionFunctionDispatcher::UIThreadResponseCallbackWrapper |
156 : public content::WebContentsObserver { | 132 : public content::WebContentsObserver { |
157 public: | 133 public: |
158 UIThreadResponseCallbackWrapper( | 134 UIThreadResponseCallbackWrapper( |
159 const base::WeakPtr<ExtensionFunctionDispatcher>& dispatcher, | 135 const base::WeakPtr<ExtensionFunctionDispatcher>& dispatcher, |
160 content::RenderFrameHost* render_frame_host) | 136 content::RenderFrameHost* render_frame_host) |
(...skipping 27 matching lines...) Expand all Loading... | |
188 weak_ptr_factory_.GetWeakPtr(), | 164 weak_ptr_factory_.GetWeakPtr(), |
189 request_id); | 165 request_id); |
190 } | 166 } |
191 | 167 |
192 private: | 168 private: |
193 void OnExtensionFunctionCompleted(int request_id, | 169 void OnExtensionFunctionCompleted(int request_id, |
194 ExtensionFunction::ResponseType type, | 170 ExtensionFunction::ResponseType type, |
195 const base::ListValue& results, | 171 const base::ListValue& results, |
196 const std::string& error, | 172 const std::string& error, |
197 functions::HistogramValue histogram_value) { | 173 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_, | 174 CommonResponseCallback(render_frame_host_, |
204 render_frame_host_->GetRoutingID(), | 175 render_frame_host_->GetRoutingID(), |
205 process, request_id, type, results, error, | 176 render_frame_host_->GetProcess(), request_id, type, |
206 histogram_value); | 177 results, error, histogram_value); |
207 } | 178 } |
208 | 179 |
209 base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_; | 180 base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_; |
210 content::RenderFrameHost* render_frame_host_; | 181 content::RenderFrameHost* render_frame_host_; |
211 base::WeakPtrFactory<UIThreadResponseCallbackWrapper> weak_ptr_factory_; | 182 base::WeakPtrFactory<UIThreadResponseCallbackWrapper> weak_ptr_factory_; |
212 | 183 |
213 DISALLOW_COPY_AND_ASSIGN(UIThreadResponseCallbackWrapper); | 184 DISALLOW_COPY_AND_ASSIGN(UIThreadResponseCallbackWrapper); |
214 }; | 185 }; |
215 | 186 |
216 class ExtensionFunctionDispatcher::UIThreadWorkerResponseCallbackWrapper | 187 class ExtensionFunctionDispatcher::UIThreadWorkerResponseCallbackWrapper |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 } | 230 } |
260 | 231 |
261 void OnExtensionFunctionCompleted(int request_id, | 232 void OnExtensionFunctionCompleted(int request_id, |
262 ExtensionFunction::ResponseType type, | 233 ExtensionFunction::ResponseType type, |
263 const base::ListValue& results, | 234 const base::ListValue& results, |
264 const std::string& error, | 235 const std::string& error, |
265 functions::HistogramValue histogram_value) { | 236 functions::HistogramValue histogram_value) { |
266 content::RenderProcessHost* sender = | 237 content::RenderProcessHost* sender = |
267 content::RenderProcessHost::FromID(render_process_id_); | 238 content::RenderProcessHost::FromID(render_process_id_); |
268 if (type == ExtensionFunction::BAD_MESSAGE) { | 239 if (type == ExtensionFunction::BAD_MESSAGE) { |
269 KillBadMessageSenderRPH(sender, histogram_value); | 240 LogBadMessage(histogram_value); |
241 bad_message::ReceivedBadMessage(sender, bad_message::EFD_BAD_MESSAGE); | |
Charlie Reis
2017/01/13 21:22:25
Please use a unique BadMessageReason in each Recei
lazyboy
2017/01/14 01:04:43
Done.
| |
270 return; | 242 return; |
271 } | 243 } |
272 DCHECK(sender); | 244 DCHECK(sender); |
273 sender->Send(new ExtensionMsg_ResponseWorker( | 245 sender->Send(new ExtensionMsg_ResponseWorker( |
274 worker_thread_id_, request_id, type == ExtensionFunction::SUCCEEDED, | 246 worker_thread_id_, request_id, type == ExtensionFunction::SUCCEEDED, |
275 results, error)); | 247 results, error)); |
276 } | 248 } |
277 | 249 |
278 base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_; | 250 base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_; |
279 ScopedObserver<content::RenderProcessHost, | 251 ScopedObserver<content::RenderProcessHost, |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
650 // static | 622 // static |
651 void ExtensionFunctionDispatcher::SendAccessDenied( | 623 void ExtensionFunctionDispatcher::SendAccessDenied( |
652 const ExtensionFunction::ResponseCallback& callback, | 624 const ExtensionFunction::ResponseCallback& callback, |
653 functions::HistogramValue histogram_value) { | 625 functions::HistogramValue histogram_value) { |
654 base::ListValue empty_list; | 626 base::ListValue empty_list; |
655 callback.Run(ExtensionFunction::FAILED, empty_list, | 627 callback.Run(ExtensionFunction::FAILED, empty_list, |
656 "Access to extension API denied.", histogram_value); | 628 "Access to extension API denied.", histogram_value); |
657 } | 629 } |
658 | 630 |
659 } // namespace extensions | 631 } // namespace extensions |
OLD | NEW |