summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/nacl/DEPS6
-rw-r--r--chrome/nacl/nacl_ipc_adapter.cc73
-rw-r--r--ppapi/proxy/resource_message_params.cc51
-rw-r--r--ppapi/proxy/resource_message_params.h16
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_;