diff options
-rw-r--r-- | chrome/nacl/DEPS | 6 | ||||
-rw-r--r-- | chrome/nacl/nacl_ipc_adapter.cc | 73 | ||||
-rw-r--r-- | ppapi/proxy/resource_message_params.cc | 51 | ||||
-rw-r--r-- | ppapi/proxy/resource_message_params.h | 16 |
4 files changed, 119 insertions, 27 deletions
diff --git a/chrome/nacl/DEPS b/chrome/nacl/DEPS index edb5129..fb99bb0 100644 --- a/chrome/nacl/DEPS +++ b/chrome/nacl/DEPS @@ -6,5 +6,9 @@ include_rules = [ "+sandbox/win/src", "+native_client/src", "+ppapi/c", # header files only - "+ppapi/proxy/ppapi_messages.h", # for message id's only + # For handle conversion in nacl_ipc_adapter.cc: + # TODO(dmichael): We should only need 1 include to ppapi/proxy for a + # HandleConverter class. crbug.com/165201 + "+ppapi/proxy/ppapi_messages.h", + "+ppapi/proxy/resource_message_params.h", ] diff --git a/chrome/nacl/nacl_ipc_adapter.cc b/chrome/nacl/nacl_ipc_adapter.cc index d7e7786..a50c714 100644 --- a/chrome/nacl/nacl_ipc_adapter.cc +++ b/chrome/nacl/nacl_ipc_adapter.cc @@ -19,6 +19,7 @@ #include "native_client/src/trusted/desc/nacl_desc_custom.h" #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" namespace { @@ -90,6 +91,8 @@ void DeleteChannel(IPC::Channel* channel) { delete channel; } +// TODO(dmichael): Move all this handle conversion code to ppapi/proxy. +// crbug.com/165201 void WriteHandle(int handle_index, const ppapi::proxy::SerializedHandle& handle, IPC::Message* message) { @@ -102,21 +105,55 @@ void WriteHandle(int handle_index, typedef std::vector<ppapi::proxy::SerializedHandle> Handles; -// We define one overload for catching SerializedHandles, so that we can share +// We define overload for catching SerializedHandles, so that we can share // them correctly to the untrusted side, and another for handling all other // parameters. See ConvertHandlesImpl for how these get used. -void ConvertHandle(const ppapi::proxy::SerializedHandle& handle, - Handles* handles, IPC::Message* msg, int* handle_index) { +void ConvertHandlesInParam(const ppapi::proxy::SerializedHandle& handle, + Handles* handles, + IPC::Message* msg, + int* handle_index) { handles->push_back(handle); if (msg) WriteHandle((*handle_index)++, handle, msg); } -// This overload is to catch all types other than SerializedHandle. On Windows, -// |msg| will be a valid pointer, and we must write |param| to it +// For PpapiMsg_ResourceReply and the reply to PpapiHostMsg_ResourceSyncCall, +// the handles are carried inside the ResourceMessageReplyParams. +// NOTE: We only translate handles from host->NaCl. The only kind of +// ResourceMessageParams that travels this direction is +// ResourceMessageReplyParams, so that's the only one we need to handle. +void ConvertHandlesInParam( + const ppapi::proxy::ResourceMessageReplyParams& params, + Handles* handles, + IPC::Message* msg, + int* handle_index) { + // First, if we need to rewrite the message parameters, write everything + // before the handles (there's nothing after the handles). + if (msg) { + params.WriteReplyHeader(msg); + // IPC writes the vector length as an int before the contents of the + // vector. + msg->WriteInt(static_cast<int>(params.handles().size())); + } + for (Handles::const_iterator iter = params.handles().begin(); + iter != params.handles().end(); + ++iter) { + // ConvertHandle will write each handle to |msg|, if necessary. + ConvertHandlesInParam(*iter, handles, msg, handle_index); + } + // Tell ResourceMessageReplyParams that we have taken the handles, so it + // shouldn't close them. The NaCl runtime will take ownership of them. + params.ConsumeHandles(); +} + +// This overload is to catch all types other than SerializedHandle or +// ResourceMessageReplyParams. On Windows, |msg| will be a valid pointer, and we +// must write |param| to it. template <class T> -void ConvertHandle(const T& param, Handles* /* handles */, IPC::Message* msg, - int* /* handle_index */) { +void ConvertHandlesInParam(const T& param, + Handles* /* handles */, + IPC::Message* msg, + int* /* handle_index */) { // It's not a handle, so just write to the output message, if necessary. if (msg) IPC::WriteParam(msg, param); @@ -131,31 +168,31 @@ template <class A> void ConvertHandlesImpl(const Tuple1<A>& t1, Handles* handles, IPC::Message* msg) { int handle_index = 0; - ConvertHandle(t1.a, handles, msg, &handle_index); + ConvertHandlesInParam(t1.a, handles, msg, &handle_index); } template <class A, class B> void ConvertHandlesImpl(const Tuple2<A, B>& t1, Handles* handles, IPC::Message* msg) { int handle_index = 0; - ConvertHandle(t1.a, handles, msg, &handle_index); - ConvertHandle(t1.b, handles, msg, &handle_index); + ConvertHandlesInParam(t1.a, handles, msg, &handle_index); + ConvertHandlesInParam(t1.b, handles, msg, &handle_index); } template <class A, class B, class C> void ConvertHandlesImpl(const Tuple3<A, B, C>& t1, Handles* handles, IPC::Message* msg) { int handle_index = 0; - ConvertHandle(t1.a, handles, msg, &handle_index); - ConvertHandle(t1.b, handles, msg, &handle_index); - ConvertHandle(t1.c, handles, msg, &handle_index); + ConvertHandlesInParam(t1.a, handles, msg, &handle_index); + ConvertHandlesInParam(t1.b, handles, msg, &handle_index); + ConvertHandlesInParam(t1.c, handles, msg, &handle_index); } template <class A, class B, class C, class D> void ConvertHandlesImpl(const Tuple4<A, B, C, D>& t1, Handles* handles, IPC::Message* msg) { int handle_index = 0; - ConvertHandle(t1.a, handles, msg, &handle_index); - ConvertHandle(t1.b, handles, msg, &handle_index); - ConvertHandle(t1.c, handles, msg, &handle_index); - ConvertHandle(t1.d, handles, msg, &handle_index); + ConvertHandlesInParam(t1.a, handles, msg, &handle_index); + ConvertHandlesInParam(t1.b, handles, msg, &handle_index); + ConvertHandlesInParam(t1.c, handles, msg, &handle_index); + ConvertHandlesInParam(t1.d, handles, msg, &handle_index); } template <class MessageType> @@ -471,6 +508,7 @@ bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& msg) { switch (msg.type()) { CASE_FOR_MESSAGE(PpapiMsg_CreateNaClChannel) CASE_FOR_MESSAGE(PpapiMsg_PPBAudio_NotifyAudioStreamCreated) + CASE_FOR_MESSAGE(PpapiPluginMsg_ResourceReply) case IPC_REPLY_ID: { int id = IPC::SyncMessage::GetMessageId(msg); LockedData::PendingSyncMsgMap::iterator iter( @@ -484,6 +522,7 @@ bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& msg) { switch (type) { CASE_FOR_REPLY(PpapiHostMsg_PPBGraphics3D_GetTransferBuffer) CASE_FOR_REPLY(PpapiHostMsg_PPBImageData_CreateNaCl) + CASE_FOR_REPLY(PpapiHostMsg_ResourceSyncCall) default: // Do nothing for messages we don't know. break; diff --git a/ppapi/proxy/resource_message_params.cc b/ppapi/proxy/resource_message_params.cc index 49b6328..e4858da 100644 --- a/ppapi/proxy/resource_message_params.cc +++ b/ppapi/proxy/resource_message_params.cc @@ -41,22 +41,46 @@ ResourceMessageParams::~ResourceMessageParams() { } void ResourceMessageParams::Serialize(IPC::Message* msg) const { + WriteHeader(msg); + WriteHandles(msg); +} + +bool ResourceMessageParams::Deserialize(const IPC::Message* msg, + PickleIterator* iter) { + return ReadHeader(msg, iter) && ReadHandles(msg, iter); +} + +void ResourceMessageParams::WriteHeader(IPC::Message* msg) const { IPC::ParamTraits<PP_Resource>::Write(msg, pp_resource_); IPC::ParamTraits<int32_t>::Write(msg, sequence_); +} + +void ResourceMessageParams::WriteHandles(IPC::Message* msg) const { IPC::ParamTraits<std::vector<SerializedHandle> >::Write(msg, handles_->data()); } -bool ResourceMessageParams::Deserialize(const IPC::Message* msg, - PickleIterator* iter) { +bool ResourceMessageParams::ReadHeader(const IPC::Message* msg, + PickleIterator* iter) { DCHECK(handles_->data().empty()); handles_->set_should_close(true); return IPC::ParamTraits<PP_Resource>::Read(msg, iter, &pp_resource_) && - IPC::ParamTraits<int32_t>::Read(msg, iter, &sequence_) && - IPC::ParamTraits<std::vector<SerializedHandle> >::Read( + IPC::ParamTraits<int32_t>::Read(msg, iter, &sequence_); +} + +bool ResourceMessageParams::ReadHandles(const IPC::Message* msg, + PickleIterator* iter) { + return IPC::ParamTraits<std::vector<SerializedHandle> >::Read( msg, iter, &handles_->data()); } +void ResourceMessageParams::ConsumeHandles() const { + // Note: we must not invalidate the handles. This is used for converting + // handles from the host OS to NaCl, and that conversion will not work if we + // invalidate the handles (see HandleConverter). + handles_->set_should_close(false); +} + SerializedHandle ResourceMessageParams::TakeHandleOfTypeAtIndex( size_t index, SerializedHandle::Type type) const { @@ -156,15 +180,24 @@ ResourceMessageReplyParams::~ResourceMessageReplyParams() { } void ResourceMessageReplyParams::Serialize(IPC::Message* msg) const { - ResourceMessageParams::Serialize(msg); - IPC::ParamTraits<int32_t>::Write(msg, result_); + // Rather than serialize all of ResourceMessageParams first, we serialize all + // non-handle data first, then the handles. When transferring to NaCl on + // Windows, we need to be able to translate Windows-style handles to POSIX- + // style handles, and it's easier to put all the regular stuff at the front. + WriteReplyHeader(msg); + WriteHandles(msg); } bool ResourceMessageReplyParams::Deserialize(const IPC::Message* msg, PickleIterator* iter) { - if (!ResourceMessageParams::Deserialize(msg, iter)) - return false; - return IPC::ParamTraits<int32_t>::Read(msg, iter, &result_); + return (ReadHeader(msg, iter) && + IPC::ParamTraits<int32_t>::Read(msg, iter, &result_) && + ReadHandles(msg, iter)); +} + +void ResourceMessageReplyParams::WriteReplyHeader(IPC::Message* msg) const { + WriteHeader(msg); + IPC::ParamTraits<int32_t>::Write(msg, result_); } } // namespace proxy diff --git a/ppapi/proxy/resource_message_params.h b/ppapi/proxy/resource_message_params.h index 6d0abea..0e42ec9 100644 --- a/ppapi/proxy/resource_message_params.h +++ b/ppapi/proxy/resource_message_params.h @@ -29,6 +29,11 @@ class PPAPI_PROXY_EXPORT ResourceMessageParams { return handles_->data(); } + // Makes ResourceMessageParams leave its handles open, even if they weren't + // taken using a Take.* function. After this call, no Take.* calls are + // allowed. + void ConsumeHandles() const; + // Returns the handle at the given index if it exists and is of the given // type. The corresponding slot in the list is set to an invalid handle. // If the index doesn't exist or the handle isn't of the given type, returns @@ -70,6 +75,14 @@ class PPAPI_PROXY_EXPORT ResourceMessageParams { virtual void Serialize(IPC::Message* msg) const; virtual bool Deserialize(const IPC::Message* msg, PickleIterator* iter); + // Writes everything except the handles to |msg|. + void WriteHeader(IPC::Message* msg) const; + // Writes the handles to |msg|. + void WriteHandles(IPC::Message* msg) const; + // Matching deserialize helpers. + bool ReadHeader(const IPC::Message* msg, PickleIterator* iter); + bool ReadHandles(const IPC::Message* msg, PickleIterator* iter); + private: class SerializedHandles : public base::RefCountedThreadSafe<SerializedHandles> { @@ -154,6 +167,9 @@ class PPAPI_PROXY_EXPORT ResourceMessageReplyParams virtual bool Deserialize(const IPC::Message* msg, PickleIterator* iter) OVERRIDE; + // Writes everything except the handles to |msg|. + void WriteReplyHeader(IPC::Message* msg) const; + private: // Pepper "result code" for the callback. int32_t result_; |