summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/host_dispatcher.cc
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-13 19:44:46 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-13 19:44:46 +0000
commit037f63fb8efeb26f6d75f9dc0a6b3380460f4ea4 (patch)
tree3833cd72196f6ff896366ef3dd6d372724737635 /ppapi/proxy/host_dispatcher.cc
parentf6ee0cde751e6b816cc68ee296ffd7d3d7219229 (diff)
downloadchromium_src-037f63fb8efeb26f6d75f9dc0a6b3380460f4ea4.zip
chromium_src-037f63fb8efeb26f6d75f9dc0a6b3380460f4ea4.tar.gz
chromium_src-037f63fb8efeb26f6d75f9dc0a6b3380460f4ea4.tar.bz2
Prevent Pepper plugin reentrancy for synchronous messages except for script
calls where reentrancy is required. Review URL: http://codereview.chromium.org/6625045 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@77967 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy/host_dispatcher.cc')
-rw-r--r--ppapi/proxy/host_dispatcher.cc34
1 files changed, 34 insertions, 0 deletions
diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc
index 52305e0..d51ad09 100644
--- a/ppapi/proxy/host_dispatcher.cc
+++ b/ppapi/proxy/host_dispatcher.cc
@@ -41,6 +41,20 @@ PP_Bool ReserveInstanceID(PP_Module module, PP_Instance instance) {
return BoolToPPBool(usable);
}
+// Saves the state of the given bool and puts it back when it goes out of
+// scope.
+class BoolRestorer {
+ public:
+ BoolRestorer(bool* var) : var_(var), old_value_(*var) {
+ }
+ ~BoolRestorer() {
+ *var_ = old_value_;
+ }
+ private:
+ bool* var_;
+ bool old_value_;
+};
+
} // namespace
HostDispatcher::HostDispatcher(base::ProcessHandle remote_process_handle,
@@ -105,7 +119,27 @@ bool HostDispatcher::IsPlugin() const {
return false;
}
+bool HostDispatcher::Send(IPC::Message* msg) {
+ // Normal sync messages are set to unblock, which would normally cause the
+ // plugin to be reentered to process them. We only want to do this when we
+ // know the plugin is in a state to accept reentrancy. Since the plugin side
+ // never clears this flag on messages it sends, we can't get deadlock, but we
+ // may still get reentrancy in the host as a result.
+ if (!allow_plugin_reentrancy_)
+ msg->set_unblock(false);
+ return Dispatcher::Send(msg);
+}
+
bool HostDispatcher::OnMessageReceived(const IPC::Message& msg) {
+ // We only want to allow reentrancy when the most recent message from the
+ // plugin was a scripting message. We save the old state of the flag on the
+ // stack in case we're (we are the host) being reentered ourselves. The flag
+ // is set to false here for all messages, and then the scripting API will
+ // explicitly set it to true during processing of those messages that can be
+ // reentered.
+ BoolRestorer restorer(&allow_plugin_reentrancy_);
+ allow_plugin_reentrancy_ = false;
+
// Handle common control messages.
if (Dispatcher::OnMessageReceived(msg))
return true;