nacl_message_scanner.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
10f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 20f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 30f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// found in the LICENSE file. 40f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 50f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/proxy/nacl_message_scanner.h" 60f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 70f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include <vector> 80f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/bind.h" 90f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ipc/ipc_message.h" 100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ipc/ipc_message_macros.h" 110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/proxy/resource_message_params.h" 130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/proxy/serialized_handle.h" 140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/proxy/serialized_var.h" 150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class NaClDescImcShm; 170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace IPC { 190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class Message; 200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace { 230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)typedef std::vector<ppapi::proxy::SerializedHandle> Handles; 250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)struct ScanningResults { 270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanningResults() : handle_index(0) {} 280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Vector to hold handles found in the message. 300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Handles handles; 310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Current handle index in the rewritten message. During the scan, it will be 320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // be less than or equal to handles.size(). After the scan it should be equal. 330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int handle_index; 340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // The rewritten message. This may be NULL, so all ScanParam overloads should 350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // check for NULL before writing to it. In some cases, a ScanParam overload 360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // may set this to NULL when it can determine that there are no parameters 370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // that need conversion. (See the ResourceMessageReplyParams overload.) 380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_ptr<IPC::Message> new_msg; 390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}; 400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void WriteHandle(int handle_index, 420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const ppapi::proxy::SerializedHandle& handle, 430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) IPC::Message* msg) { 440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::proxy::SerializedHandle::WriteHeader(handle.header(), msg); 450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Now write the handle itself in POSIX style. 470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) msg->WriteBool(true); // valid == true 480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) msg->WriteInt(handle_index); 490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Define overloads for each kind of message parameter that requires special 520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// handling. See ScanTuple for how these get used. 530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Overload to match SerializedHandle. 550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void ScanParam(const ppapi::proxy::SerializedHandle& handle, 560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanningResults* results) { 570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) results->handles.push_back(handle); 580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (results->new_msg) 590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) WriteHandle(results->handle_index++, handle, results->new_msg.get()); 600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void HandleWriter(int* handle_index, 630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) IPC::Message* m, 640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const ppapi::proxy::SerializedHandle& handle) { 650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) WriteHandle((*handle_index)++, handle, m); 660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Overload to match SerializedVar, which can contain handles. 690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void ScanParam(const ppapi::proxy::SerializedVar& var, 700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanningResults* results) { 710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) std::vector<ppapi::proxy::SerializedHandle*> var_handles = var.GetHandles(); 720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Copy any handles and then rewrite the message. 730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) for (size_t i = 0; i < var_handles.size(); ++i) 740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) results->handles.push_back(*var_handles[i]); 750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (results->new_msg) 760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) var.WriteDataToMessage(results->new_msg.get(), 770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::Bind(&HandleWriter, &results->handle_index)); 780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// For PpapiMsg_ResourceReply and the reply to PpapiHostMsg_ResourceSyncCall, 810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// the handles are carried inside the ResourceMessageReplyParams. 820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// NOTE: We only intercept handles from host->NaCl. The only kind of 830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// ResourceMessageParams that travels this direction is 840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// ResourceMessageReplyParams, so that's the only one we need to handle. 850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void ScanParam(const ppapi::proxy::ResourceMessageReplyParams& params, 860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanningResults* results) { 870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // If the resource reply params don't contain handles, NULL the new message 880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // pointer to cancel further rewriting. 890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // NOTE: This works because only handles currently need rewriting, and we 900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // know at this point that this message has none. 910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (params.handles().empty()) { 920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) results->new_msg.reset(NULL); 930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return; 940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // If we need to rewrite the message, write everything before the handles 970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // (there's nothing after the handles). 980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (results->new_msg) { 990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) params.WriteReplyHeader(results->new_msg.get()); 1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // IPC writes the vector length as an int before the contents of the 1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // vector. 1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) results->new_msg->WriteInt(static_cast<int>(params.handles().size())); 1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) for (Handles::const_iterator iter = params.handles().begin(); 1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) iter != params.handles().end(); 1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ++iter) { 1070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // ScanParam will write each handle to the new message, if necessary. 1080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanParam(*iter, results); 1090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Tell ResourceMessageReplyParams that we have taken the handles, so it 1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // shouldn't close them. The NaCl runtime will take ownership of them. 1120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) params.ConsumeHandles(); 1130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Overload to match all other types. If we need to rewrite the message, 1160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// write the parameter. 1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)template <class T> 1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void ScanParam(const T& param, ScanningResults* results) { 1190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (results->new_msg) 1200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) IPC::WriteParam(results->new_msg.get(), param); 1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// These just break apart the given tuple and run ScanParam over each param. 1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// The idea is to scan elements in the tuple which require special handling, 1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// and write them into the |results| struct. 1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)template <class A> 1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void ScanTuple(const Tuple1<A>& t1, ScanningResults* results) { 1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanParam(t1.a, results); 1290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)template <class A, class B> 1310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void ScanTuple(const Tuple2<A, B>& t1, ScanningResults* results) { 1320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanParam(t1.a, results); 1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanParam(t1.b, results); 1340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)template <class A, class B, class C> 1360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void ScanTuple(const Tuple3<A, B, C>& t1, ScanningResults* results) { 1370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanParam(t1.a, results); 1380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanParam(t1.b, results); 1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanParam(t1.c, results); 1400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)template <class A, class B, class C, class D> 1420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void ScanTuple(const Tuple4<A, B, C, D>& t1, ScanningResults* results) { 1430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanParam(t1.a, results); 1440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanParam(t1.b, results); 1450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanParam(t1.c, results); 1460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanParam(t1.d, results); 1470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)template <class MessageType> 1500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class MessageScannerImpl { 1510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public: 1520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) explicit MessageScannerImpl(const IPC::Message* msg) 1530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) : msg_(static_cast<const MessageType*>(msg)) { 1540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bool ScanMessage(ScanningResults* results) { 1560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) typename TupleTypes<typename MessageType::Schema::Param>::ValueTuple params; 1570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!MessageType::Read(msg_, ¶ms)) 1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return false; 1590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanTuple(params, results); 1600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return true; 1610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bool ScanReply(ScanningResults* results) { 1640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) typename TupleTypes<typename MessageType::Schema::ReplyParam>::ValueTuple 1650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) params; 1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!MessageType::ReadReplyParam(msg_, ¶ms)) 1670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return false; 1680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // If we need to rewrite the message, write the message id first. 1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (results->new_msg) { 1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) results->new_msg->set_reply(); 1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int id = IPC::SyncMessage::GetMessageId(*msg_); 1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) results->new_msg->WriteInt(id); 1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanTuple(params, results); 1750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return true; 1760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // TODO(dmichael): Add ScanSyncMessage for outgoing sync messages, if we ever 1780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // need to scan those. 1790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private: 1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const MessageType* msg_; 1820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}; 1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} // namespace 1850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#define CASE_FOR_MESSAGE(MESSAGE_TYPE) \ 1870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) case MESSAGE_TYPE::ID: { \ 1880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) MessageScannerImpl<MESSAGE_TYPE> scanner(&msg); \ 1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (rewrite_msg) \ 1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) results.new_msg.reset( \ 1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) new IPC::Message(msg.routing_id(), msg.type(), \ 1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) IPC::Message::PRIORITY_NORMAL)); \ 1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!scanner.ScanMessage(&results)) \ 1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return false; \ 1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) break; \ 1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#define CASE_FOR_REPLY(MESSAGE_TYPE) \ 1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) case MESSAGE_TYPE::ID: { \ 1990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) MessageScannerImpl<MESSAGE_TYPE> scanner(&msg); \ 2000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (rewrite_msg) \ 2010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) results.new_msg.reset( \ 2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) new IPC::Message(msg.routing_id(), msg.type(), \ 2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) IPC::Message::PRIORITY_NORMAL)); \ 2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!scanner.ScanReply(&results)) \ 2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return false; \ 2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) break; \ 2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 2080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace ppapi { 2100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace proxy { 2110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class SerializedHandle; 2130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)NaClMessageScanner::NaClMessageScanner() { 2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 2160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Windows IPC differs from POSIX in that native handles are serialized in the 2180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// message body, rather than passed in a separate FileDescriptorSet. Therefore, 2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// on Windows, any message containing handles must be rewritten in the POSIX 2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// format before we can send it to the NaCl plugin. 2210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// 2220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// On POSIX and Windows we have to rewrite PpapiMsg_CreateNaClChannel messages. 2230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// These contain a handle with an invalid (place holder) descriptor. We need to 2240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// locate this handle so it can be replaced with a valid one when the channel is 2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// created. 2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)bool NaClMessageScanner::ScanMessage( 2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const IPC::Message& msg, 2280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) std::vector<SerializedHandle>* handles, 2290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_ptr<IPC::Message>* new_msg_ptr) { 2300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(handles); 2310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(handles->empty()); 2320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(new_msg_ptr); 2330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(!new_msg_ptr->get()); 2340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bool rewrite_msg = 2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(OS_WIN) 2370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) true; 2380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#else 2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) (msg.type() == PpapiMsg_CreateNaClChannel::ID); 2400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif 2410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // We can't always tell from the message ID if rewriting is needed. Therefore, 2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // scan any message types that might contain a handle. If we later determine 2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // that there are no handles, we can cancel the rewriting by clearing the 2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // results.new_msg pointer. 2470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ScanningResults results; 2480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) switch (msg.type()) { 2490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CASE_FOR_MESSAGE(PpapiMsg_CreateNaClChannel) 2500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CASE_FOR_MESSAGE(PpapiMsg_PPBAudio_NotifyAudioStreamCreated) 2510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CASE_FOR_MESSAGE(PpapiMsg_PPPMessaging_HandleMessage) 2520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CASE_FOR_MESSAGE(PpapiPluginMsg_ResourceReply) 2530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) case IPC_REPLY_ID: { 2540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int id = IPC::SyncMessage::GetMessageId(msg); 2550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) PendingSyncMsgMap::iterator iter(pending_sync_msgs_.find(id)); 2560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (iter == pending_sync_msgs_.end()) { 2570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) NOTREACHED(); 2580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return false; 2590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 2600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) uint32_t type = iter->second; 2610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) pending_sync_msgs_.erase(iter); 2620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) switch (type) { 2630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CASE_FOR_REPLY(PpapiHostMsg_PPBGraphics3D_GetTransferBuffer) 2640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CASE_FOR_REPLY(PpapiHostMsg_PPBImageData_CreateSimple) 2650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CASE_FOR_REPLY(PpapiHostMsg_ResourceSyncCall) 2660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CASE_FOR_REPLY(PpapiHostMsg_SharedMemory_CreateSharedMemory) 2670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) default: 2680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Do nothing for messages we don't know. 2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) break; 2700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 2710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) break; 2720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 2730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) default: 2740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Do nothing for messages we don't know. 2750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) break; 2760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 2770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Only messages containing handles need to be rewritten. If no handles are 2790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // found, don't return the rewritten message either. This must be changed if 2800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // we ever add new param types that also require rewriting. 2810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!results.handles.empty()) { 2820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) handles->swap(results.handles); 2830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) *new_msg_ptr = results.new_msg.Pass(); 2840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 2850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return true; 2860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 2870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void NaClMessageScanner::RegisterSyncMessageForReply(const IPC::Message& msg) { 2890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(msg.is_sync()); 2900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int msg_id = IPC::SyncMessage::GetMessageId(msg); 2920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(pending_sync_msgs_.find(msg_id) == pending_sync_msgs_.end()); 2930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) pending_sync_msgs_[msg_id] = msg.type(); 2950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 2960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} // namespace proxy 2980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} // namespace ppapi 299