// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ppapi/proxy/nacl_message_scanner.h"

#include <vector>
#include "base/bind.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_message_params.h"
#include "ppapi/proxy/serialized_handle.h"
#include "ppapi/proxy/serialized_var.h"

class NaClDescImcShm;

namespace IPC {
class Message;
}

using ppapi::proxy::ResourceMessageReplyParams;
using ppapi::proxy::SerializedHandle;
using ppapi::proxy::SerializedVar;

namespace {

typedef std::vector<SerializedHandle> Handles;

struct ScanningResults {
  ScanningResults() : handle_index(0), pp_resource(0) {}

  // Vector to hold handles found in the message.
  Handles handles;
  // Current handle index in the rewritten message. During the scan, it will be
  // be less than or equal to handles.size(). After the scan it should be equal.
  int handle_index;
  // The rewritten message. This may be NULL, so all ScanParam overloads should
  // check for NULL before writing to it. In some cases, a ScanParam overload
  // may set this to NULL when it can determine that there are no parameters
  // that need conversion. (See the ResourceMessageReplyParams overload.)
  scoped_ptr<IPC::Message> new_msg;
  // Resource id for resource messages. Save this when scanning resource replies
  // so when we audit the nested message, we know which resource it is for.
  PP_Resource pp_resource;
  // Callback to receive the nested message in a resource message or reply.
  base::Callback<void(PP_Resource, const IPC::Message&, SerializedHandle*)>
      nested_msg_callback;
};

void WriteHandle(int handle_index,
                 const SerializedHandle& handle,
                 IPC::Message* msg) {
  SerializedHandle::WriteHeader(handle.header(), msg);

  if (handle.type() != SerializedHandle::INVALID) {
    // Now write the handle itself in POSIX style.
    // See ParamTraits<FileDescriptor>::Read for where these values are read.
    msg->WriteBool(true);  // valid == true
    msg->WriteInt(handle_index);
  }
}

// Define overloads for each kind of message parameter that requires special
// handling. See ScanTuple for how these get used.

// Overload to match SerializedHandle.
void ScanParam(const SerializedHandle& handle, ScanningResults* results) {
  results->handles.push_back(handle);
  if (results->new_msg)
    WriteHandle(results->handle_index++, handle, results->new_msg.get());
}

void HandleWriter(int* handle_index,
                  IPC::Message* m,
                  const SerializedHandle& handle) {
  WriteHandle((*handle_index)++, handle, m);
}

// Overload to match SerializedVar, which can contain handles.
void ScanParam(const SerializedVar& var, ScanningResults* results) {
  std::vector<SerializedHandle*> var_handles = var.GetHandles();
  // Copy any handles and then rewrite the message.
  for (size_t i = 0; i < var_handles.size(); ++i)
    results->handles.push_back(*var_handles[i]);
  if (results->new_msg)
    var.WriteDataToMessage(results->new_msg.get(),
                           base::Bind(&HandleWriter, &results->handle_index));
}

// For PpapiMsg_ResourceReply and the reply to PpapiHostMsg_ResourceSyncCall,
// the handles are carried inside the ResourceMessageReplyParams.
// NOTE: We only intercept 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 ScanParam(const ResourceMessageReplyParams& params,
               ScanningResults* results) {
  results->pp_resource = params.pp_resource();
  // If the resource reply params don't contain handles, NULL the new message
  // pointer to cancel further rewriting.
  // NOTE: This works because only handles currently need rewriting, and we
  //       know at this point that this message has none.
  if (params.handles().empty()) {
    results->new_msg.reset(NULL);
    return;
  }

  // If we need to rewrite the message, write everything before the handles
  // (there's nothing after the handles).
  if (results->new_msg) {
    params.WriteReplyHeader(results->new_msg.get());
    // IPC writes the vector length as an int before the contents of the
    // vector.
    results->new_msg->WriteInt(static_cast<int>(params.handles().size()));
  }
  for (Handles::const_iterator iter = params.handles().begin();
       iter != params.handles().end();
       ++iter) {
    // ScanParam will write each handle to the new message, if necessary.
    ScanParam(*iter, results);
  }
  // Tell ResourceMessageReplyParams that we have taken the handles, so it
  // shouldn't close them. The NaCl runtime will take ownership of them.
  params.ConsumeHandles();
}

// Overload to match nested messages. If we need to rewrite the message, write
// the parameter.
void ScanParam(const IPC::Message& param, ScanningResults* results) {
  if (results->pp_resource && !results->nested_msg_callback.is_null()) {
    SerializedHandle* handle = NULL;
    if (results->handles.size() == 1)
      handle = &results->handles[0];
    results->nested_msg_callback.Run(results->pp_resource, param, handle);
  }
  if (results->new_msg)
    IPC::WriteParam(results->new_msg.get(), param);
}

// Overload to match all other types. If we need to rewrite the message, write
// the parameter.
template <class T>
void ScanParam(const T& param, ScanningResults* results) {
  if (results->new_msg)
    IPC::WriteParam(results->new_msg.get(), param);
}

// These just break apart the given tuple and run ScanParam over each param.
// The idea is to scan elements in the tuple which require special handling,
// and write them into the |results| struct.
template <class A>
void ScanTuple(const base::Tuple<A>& t1, ScanningResults* results) {
  ScanParam(base::get<0>(t1), results);
}
template <class A, class B>
void ScanTuple(const base::Tuple<A, B>& t1, ScanningResults* results) {
  ScanParam(base::get<0>(t1), results);
  ScanParam(base::get<1>(t1), results);
}
template <class A, class B, class C>
void ScanTuple(const base::Tuple<A, B, C>& t1, ScanningResults* results) {
  ScanParam(base::get<0>(t1), results);
  ScanParam(base::get<1>(t1), results);
  ScanParam(base::get<2>(t1), results);
}
template <class A, class B, class C, class D>
void ScanTuple(const base::Tuple<A, B, C, D>& t1, ScanningResults* results) {
  ScanParam(base::get<0>(t1), results);
  ScanParam(base::get<1>(t1), results);
  ScanParam(base::get<2>(t1), results);
  ScanParam(base::get<3>(t1), results);
}

template <class MessageType>
class MessageScannerImpl {
 public:
  explicit MessageScannerImpl(const IPC::Message* msg)
      : msg_(static_cast<const MessageType*>(msg)) {
  }
  bool ScanMessage(ScanningResults* results) {
    typename base::TupleTypes<typename MessageType::Schema::Param>::ValueTuple
        params;
    if (!MessageType::Read(msg_, &params))
      return false;
    ScanTuple(params, results);
    return true;
  }

  bool ScanReply(ScanningResults* results) {
    typename base::TupleTypes<typename MessageType::Schema::ReplyParam>
        ::ValueTuple params;
    if (!MessageType::ReadReplyParam(msg_, &params))
      return false;
    // If we need to rewrite the message, write the message id first.
    if (results->new_msg) {
      results->new_msg->set_reply();
      int id = IPC::SyncMessage::GetMessageId(*msg_);
      results->new_msg->WriteInt(id);
    }
    ScanTuple(params, results);
    return true;
  }
  // TODO(dmichael): Add ScanSyncMessage for outgoing sync messages, if we ever
  //                 need to scan those.

 private:
  const MessageType* msg_;
};

}  // namespace

#define CASE_FOR_MESSAGE(MESSAGE_TYPE) \
      case MESSAGE_TYPE::ID: { \
        MessageScannerImpl<MESSAGE_TYPE> scanner(&msg); \
        if (rewrite_msg) \
          results.new_msg.reset( \
              new IPC::Message(msg.routing_id(), msg.type(), \
                               IPC::Message::PRIORITY_NORMAL)); \
        if (!scanner.ScanMessage(&results)) \
          return false; \
        break; \
      }
#define CASE_FOR_REPLY(MESSAGE_TYPE) \
      case MESSAGE_TYPE::ID: { \
        MessageScannerImpl<MESSAGE_TYPE> scanner(&msg); \
        if (rewrite_msg) \
          results.new_msg.reset( \
              new IPC::Message(msg.routing_id(), msg.type(), \
                               IPC::Message::PRIORITY_NORMAL)); \
        if (!scanner.ScanReply(&results)) \
          return false; \
        break; \
      }

namespace ppapi {
namespace proxy {

class SerializedHandle;

NaClMessageScanner::FileSystem::FileSystem()
    : reserved_quota_(0) {
}

NaClMessageScanner::FileSystem::~FileSystem() {
}

bool NaClMessageScanner::FileSystem::UpdateReservedQuota(int64_t delta) {
  base::AutoLock lock(lock_);
  if (std::numeric_limits<int64_t>::max() - reserved_quota_ < delta)
    return false;  // reserved_quota_ + delta would overflow.
  if (reserved_quota_ + delta < 0)
    return false;
  reserved_quota_ += delta;
  return true;
}

NaClMessageScanner::FileIO::FileIO(FileSystem* file_system,
                                   int64_t max_written_offset)
    : file_system_(file_system),
      max_written_offset_(max_written_offset) {
}

NaClMessageScanner::FileIO::~FileIO() {
}

void NaClMessageScanner::FileIO::SetMaxWrittenOffset(
    int64_t max_written_offset) {
  base::AutoLock lock(lock_);
  max_written_offset_ = max_written_offset;
}

bool NaClMessageScanner::FileIO::Grow(int64_t amount) {
  base::AutoLock lock(lock_);
  DCHECK(amount > 0);
  if (!file_system_->UpdateReservedQuota(-amount))
    return false;
  max_written_offset_ += amount;
  return true;
}

NaClMessageScanner::NaClMessageScanner() {
}

NaClMessageScanner::~NaClMessageScanner() {
  for (FileSystemMap::iterator it = file_systems_.begin();
      it != file_systems_.end(); ++it)
    delete it->second;
  for (FileIOMap::iterator it = files_.begin(); it != files_.end(); ++it)
    delete it->second;
}

// Windows IPC differs from POSIX in that native handles are serialized in the
// message body, rather than passed in a separate FileDescriptorSet. Therefore,
// on Windows, any message containing handles must be rewritten in the POSIX
// format before we can send it to the NaCl plugin.
// On Mac, base::SharedMemoryHandle has a different serialization than
// base::FileDescriptor (which base::SharedMemoryHandle is typedef-ed to in
// OS_NACL).
bool NaClMessageScanner::ScanMessage(
    const IPC::Message& msg,
    uint32_t type,
    std::vector<SerializedHandle>* handles,
    scoped_ptr<IPC::Message>* new_msg_ptr) {
  DCHECK(handles);
  DCHECK(handles->empty());
  DCHECK(new_msg_ptr);
  DCHECK(!new_msg_ptr->get());

  bool rewrite_msg =
#if defined(OS_WIN) || defined(OS_MACOSX)
      true;
#else
      false;
#endif

  // We can't always tell from the message ID if rewriting is needed. Therefore,
  // scan any message types that might contain a handle. If we later determine
  // that there are no handles, we can cancel the rewriting by clearing the
  // results.new_msg pointer.
  ScanningResults results;
  results.nested_msg_callback =
      base::Bind(&NaClMessageScanner::AuditNestedMessage,
                 base::Unretained(this));
  switch (type) {
    CASE_FOR_MESSAGE(PpapiMsg_PPBAudio_NotifyAudioStreamCreated)
    CASE_FOR_MESSAGE(PpapiMsg_PPPMessaging_HandleMessage)
    CASE_FOR_MESSAGE(PpapiPluginMsg_ResourceReply)
    CASE_FOR_REPLY(PpapiHostMsg_OpenResource)
    CASE_FOR_REPLY(PpapiHostMsg_PPBGraphics3D_Create)
    CASE_FOR_REPLY(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer)
    CASE_FOR_REPLY(PpapiHostMsg_PPBImageData_CreateSimple)
    CASE_FOR_REPLY(PpapiHostMsg_ResourceSyncCall)
    CASE_FOR_REPLY(PpapiHostMsg_SharedMemory_CreateSharedMemory)
    default:
      // Do nothing for messages we don't know.
      break;
  }

  // Only messages containing handles need to be rewritten. If no handles are
  // found, don't return the rewritten message either. This must be changed if
  // we ever add new param types that also require rewriting.
  if (!results.handles.empty()) {
    handles->swap(results.handles);
    *new_msg_ptr = results.new_msg.Pass();
  }
  return true;
}

void NaClMessageScanner::ScanUntrustedMessage(
    const IPC::Message& untrusted_msg,
    scoped_ptr<IPC::Message>* new_msg_ptr) {
  // Audit FileIO and FileSystem messages to ensure that the plugin doesn't
  // exceed its file quota. If we find the message is malformed, just pass it
  // through - we only care about well formed messages to the host.
  if (untrusted_msg.type() == PpapiHostMsg_ResourceCall::ID) {
    ResourceMessageCallParams params;
    IPC::Message nested_msg;
    if (!UnpackMessage<PpapiHostMsg_ResourceCall>(
            untrusted_msg, &params, &nested_msg))
      return;

    switch (nested_msg.type()) {
      case PpapiHostMsg_FileIO_Close::ID: {
        FileIOMap::iterator it = files_.find(params.pp_resource());
        if (it == files_.end())
          return;
        // Audit FileIO Close messages to make sure the plugin reports an
        // accurate file size.
        FileGrowth file_growth;
        if (!UnpackMessage<PpapiHostMsg_FileIO_Close>(
                nested_msg, &file_growth))
          return;

        int64_t trusted_max_written_offset = it->second->max_written_offset();
        delete it->second;
        files_.erase(it);
        // If the plugin is under-reporting, rewrite the message with the
        // trusted value.
        if (trusted_max_written_offset > file_growth.max_written_offset) {
          new_msg_ptr->reset(
              new PpapiHostMsg_ResourceCall(
                  params,
                  PpapiHostMsg_FileIO_Close(
                      FileGrowth(trusted_max_written_offset, 0))));
        }
        break;
      }
      case PpapiHostMsg_FileIO_SetLength::ID: {
        FileIOMap::iterator it = files_.find(params.pp_resource());
        if (it == files_.end())
          return;
        // Audit FileIO SetLength messages to make sure the plugin is within
        // the current quota reservation. In addition, deduct the file size
        // increase from the quota reservation.
        int64_t length = 0;
        if (!UnpackMessage<PpapiHostMsg_FileIO_SetLength>(
                nested_msg, &length))
          return;

        // Calculate file size increase, taking care to avoid overflows.
        if (length < 0)
          return;
        int64_t trusted_max_written_offset = it->second->max_written_offset();
        int64_t increase = length - trusted_max_written_offset;
        if (increase <= 0)
          return;
        if (!it->second->Grow(increase)) {
          new_msg_ptr->reset(
              new PpapiHostMsg_ResourceCall(
                  params,
                  PpapiHostMsg_FileIO_SetLength(-1)));
        }
        break;
      }
      case PpapiHostMsg_FileSystem_ReserveQuota::ID: {
        // Audit FileSystem ReserveQuota messages to make sure the plugin
        // reports accurate file sizes.
        int64_t amount = 0;
        FileGrowthMap file_growths;
        if (!UnpackMessage<PpapiHostMsg_FileSystem_ReserveQuota>(
                nested_msg, &amount, &file_growths))
          return;

        bool audit_failed = false;
        for (FileGrowthMap::iterator it = file_growths.begin();
            it != file_growths.end(); ++it) {
          FileIOMap::iterator file_it = files_.find(it->first);
          if (file_it == files_.end())
            continue;
          int64_t trusted_max_written_offset =
              file_it->second->max_written_offset();
          if (trusted_max_written_offset > it->second.max_written_offset) {
            audit_failed = true;
            it->second.max_written_offset = trusted_max_written_offset;
          }
          if (it->second.append_mode_write_amount < 0) {
            audit_failed = true;
            it->second.append_mode_write_amount = 0;
          }
        }
        if (audit_failed) {
          new_msg_ptr->reset(
              new PpapiHostMsg_ResourceCall(
                  params,
                  PpapiHostMsg_FileSystem_ReserveQuota(
                      amount, file_growths)));
        }
        break;
      }
      case PpapiHostMsg_ResourceDestroyed::ID: {
        // Audit resource destroyed messages to release FileSystems.
        PP_Resource resource;
        if (!UnpackMessage<PpapiHostMsg_ResourceDestroyed>(
                nested_msg, &resource))
          return;
        FileSystemMap::iterator fs_it = file_systems_.find(resource);
        if (fs_it != file_systems_.end()) {
          delete fs_it->second;
          file_systems_.erase(fs_it);
        }
        break;
      }
    }
  }
}

NaClMessageScanner::FileIO* NaClMessageScanner::GetFile(
    PP_Resource file_io) {
  FileIOMap::iterator it = files_.find(file_io);
  DCHECK(it != files_.end());
  return it->second;
}

void NaClMessageScanner::AuditNestedMessage(PP_Resource resource,
                                            const IPC::Message& msg,
                                            SerializedHandle* handle) {
  switch (msg.type()) {
    case PpapiPluginMsg_FileIO_OpenReply::ID: {
      // A file that requires quota checking was opened.
      PP_Resource quota_file_system;
      int64_t max_written_offset = 0;
      if (ppapi::UnpackMessage<PpapiPluginMsg_FileIO_OpenReply>(
              msg, &quota_file_system, &max_written_offset)) {
        if (quota_file_system) {
          // Look up the FileSystem by inserting a new one. If it was already
          // present, get the existing one, otherwise construct it.
          FileSystem* file_system = NULL;
          std::pair<FileSystemMap::iterator, bool> insert_result =
              file_systems_.insert(std::make_pair(quota_file_system,
                                                  file_system));
          if (insert_result.second)
            insert_result.first->second = new FileSystem();
          file_system = insert_result.first->second;
          // Create the FileIO.
          DCHECK(files_.find(resource) == files_.end());
          files_.insert(std::make_pair(
              resource,
              new FileIO(file_system, max_written_offset)));
        }
      }
      break;
    }
    case PpapiPluginMsg_FileSystem_ReserveQuotaReply::ID: {
      // The amount of reserved quota for a FileSystem was refreshed.
      int64_t amount = 0;
      FileSizeMap file_sizes;
      if (ppapi::UnpackMessage<PpapiPluginMsg_FileSystem_ReserveQuotaReply>(
          msg, &amount, &file_sizes)) {
        FileSystemMap::iterator it = file_systems_.find(resource);
        DCHECK(it != file_systems_.end());
        it->second->UpdateReservedQuota(amount);

        FileSizeMap::const_iterator offset_it = file_sizes.begin();
        for (; offset_it != file_sizes.end(); ++offset_it) {
          FileIOMap::iterator fio_it = files_.find(offset_it->first);
          DCHECK(fio_it != files_.end());
          if (fio_it != files_.end())
            fio_it->second->SetMaxWrittenOffset(offset_it->second);
        }
      }
      break;
    }
  }
}

}  // namespace proxy
}  // namespace ppapi
