Index: ipc/ipc_message_attachment_set.cc |
diff --git a/ipc/ipc_message_attachment_set.cc b/ipc/ipc_message_attachment_set.cc |
index b9a990da8bb6af5e498b70ffe64bef3fb9bdb6f2..068e9d29c8f326bb17227881ef3ff494f01bd4de 100644 |
--- a/ipc/ipc_message_attachment_set.cc |
+++ b/ipc/ipc_message_attachment_set.cc |
@@ -11,7 +11,15 @@ |
#include "base/logging.h" |
#include "base/posix/eintr_wrapper.h" |
#include "build/build_config.h" |
+#include "ipc/brokerable_attachment.h" |
#include "ipc/ipc_message_attachment.h" |
+ |
+#if defined(OS_POSIX) |
+#include <sys/stat.h> |
+#include <sys/types.h> |
+#include <unistd.h> |
+#include "ipc/ipc_platform_file_attachment_posix.h" |
+#endif // OS_POSIX |
namespace IPC { |
@@ -35,7 +43,7 @@ |
} |
MessageAttachmentSet::~MessageAttachmentSet() { |
- if (consumed_descriptor_highwater_ == size()) |
+ if (consumed_descriptor_highwater_ == num_non_brokerable_attachments()) |
return; |
// We close all the owning descriptors. If this message should have |
@@ -46,24 +54,39 @@ |
// (which could a DOS against the browser by a rogue renderer) then all |
// the descriptors have their close flag set and we free all the extra |
// kernel resources. |
- LOG(WARNING) << "MessageAttachmentSet destroyed with unconsumed attachments: " |
- << consumed_descriptor_highwater_ << "/" << size(); |
+ LOG(WARNING) << "MessageAttachmentSet destroyed with unconsumed descriptors: " |
+ << consumed_descriptor_highwater_ << "/" << num_descriptors(); |
} |
unsigned MessageAttachmentSet::num_descriptors() const { |
return count_attachments_of_type(attachments_, |
- MessageAttachment::Type::PLATFORM_FILE); |
+ MessageAttachment::TYPE_PLATFORM_FILE); |
+} |
+ |
+unsigned MessageAttachmentSet::num_mojo_handles() const { |
+ return count_attachments_of_type(attachments_, |
+ MessageAttachment::TYPE_MOJO_HANDLE); |
+} |
+ |
+unsigned MessageAttachmentSet::num_brokerable_attachments() const { |
+ return static_cast<unsigned>(brokerable_attachments_.size()); |
+} |
+ |
+unsigned MessageAttachmentSet::num_non_brokerable_attachments() const { |
+ return static_cast<unsigned>(attachments_.size()); |
} |
unsigned MessageAttachmentSet::size() const { |
- return static_cast<unsigned>(attachments_.size()); |
+ return static_cast<unsigned>(attachments_.size() + |
+ brokerable_attachments_.size()); |
} |
bool MessageAttachmentSet::AddAttachment( |
scoped_refptr<MessageAttachment> attachment, |
- size_t* index) { |
+ size_t* index, |
+ bool* brokerable) { |
#if defined(OS_POSIX) |
- if (attachment->GetType() == MessageAttachment::Type::PLATFORM_FILE && |
+ if (attachment->GetType() == MessageAttachment::TYPE_PLATFORM_FILE && |
num_descriptors() == kMaxDescriptorsPerMessage) { |
DLOG(WARNING) << "Cannot add file descriptor. MessageAttachmentSet full."; |
return false; |
@@ -71,12 +94,19 @@ |
#endif |
switch (attachment->GetType()) { |
- case MessageAttachment::Type::PLATFORM_FILE: |
- case MessageAttachment::Type::MOJO_HANDLE: |
- case MessageAttachment::Type::WIN_HANDLE: |
- case MessageAttachment::Type::MACH_PORT: |
+ case MessageAttachment::TYPE_PLATFORM_FILE: |
+ case MessageAttachment::TYPE_MOJO_HANDLE: |
attachments_.push_back(attachment); |
*index = attachments_.size() - 1; |
+ *brokerable = false; |
+ return true; |
+ case MessageAttachment::TYPE_BROKERABLE_ATTACHMENT: |
+ BrokerableAttachment* brokerable_attachment = |
+ static_cast<BrokerableAttachment*>(attachment.get()); |
+ scoped_refptr<BrokerableAttachment> a(brokerable_attachment); |
+ brokerable_attachments_.push_back(a); |
+ *index = brokerable_attachments_.size() - 1; |
+ *brokerable = true; |
return true; |
} |
return false; |
@@ -84,14 +114,16 @@ |
bool MessageAttachmentSet::AddAttachment( |
scoped_refptr<MessageAttachment> attachment) { |
+ bool brokerable; |
size_t index; |
- return AddAttachment(attachment, &index); |
-} |
- |
-scoped_refptr<MessageAttachment> MessageAttachmentSet::GetAttachmentAt( |
- unsigned index) { |
- if (index >= size()) { |
- DLOG(WARNING) << "Accessing out of bound index:" << index << "/" << size(); |
+ return AddAttachment(attachment, &index, &brokerable); |
+} |
+ |
+scoped_refptr<MessageAttachment> |
+MessageAttachmentSet::GetNonBrokerableAttachmentAt(unsigned index) { |
+ if (index >= num_non_brokerable_attachments()) { |
+ DLOG(WARNING) << "Accessing out of bound index:" << index << "/" |
+ << num_non_brokerable_attachments(); |
return scoped_refptr<MessageAttachment>(); |
} |
@@ -116,7 +148,8 @@ |
// end of the array and index 0 is requested, we reset the highwater value. |
// TODO(morrita): This is absurd. This "wringle" disallow to introduce clearer |
// ownership model. Only client is NaclIPCAdapter. See crbug.com/415294 |
- if (index == 0 && consumed_descriptor_highwater_ == size()) { |
+ if (index == 0 && |
+ consumed_descriptor_highwater_ == num_non_brokerable_attachments()) { |
consumed_descriptor_highwater_ = 0; |
} |
@@ -126,6 +159,19 @@ |
consumed_descriptor_highwater_ = index + 1; |
return attachments_[index]; |
+} |
+ |
+scoped_refptr<MessageAttachment> |
+MessageAttachmentSet::GetBrokerableAttachmentAt(unsigned index) { |
+ if (index >= num_brokerable_attachments()) { |
+ DLOG(WARNING) << "Accessing out of bound index:" << index << "/" |
+ << num_brokerable_attachments(); |
+ return scoped_refptr<MessageAttachment>(); |
+ } |
+ |
+ scoped_refptr<BrokerableAttachment> brokerable_attachment( |
+ brokerable_attachments_[index]); |
+ return scoped_refptr<MessageAttachment>(brokerable_attachment.get()); |
} |
void MessageAttachmentSet::CommitAllDescriptors() { |
@@ -133,4 +179,55 @@ |
consumed_descriptor_highwater_ = 0; |
} |
+std::vector<scoped_refptr<IPC::BrokerableAttachment>> |
+MessageAttachmentSet::GetBrokerableAttachments() const { |
+ return brokerable_attachments_; |
+} |
+ |
+#if defined(OS_POSIX) |
+ |
+void MessageAttachmentSet::PeekDescriptors(base::PlatformFile* buffer) const { |
+ for (size_t i = 0; i != attachments_.size(); ++i) |
+ buffer[i] = internal::GetPlatformFile(attachments_[i]); |
+} |
+ |
+bool MessageAttachmentSet::ContainsDirectoryDescriptor() const { |
+ struct stat st; |
+ |
+ for (auto i = attachments_.begin(); i != attachments_.end(); ++i) { |
+ if (fstat(internal::GetPlatformFile(*i), &st) == 0 && S_ISDIR(st.st_mode)) |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
+void MessageAttachmentSet::ReleaseFDsToClose( |
+ std::vector<base::PlatformFile>* fds) { |
+ for (size_t i = 0; i < attachments_.size(); ++i) { |
+ internal::PlatformFileAttachment* file = |
+ static_cast<internal::PlatformFileAttachment*>(attachments_[i].get()); |
+ if (file->Owns()) |
+ fds->push_back(file->TakePlatformFile()); |
+ } |
+ |
+ CommitAllDescriptors(); |
+} |
+ |
+void MessageAttachmentSet::AddDescriptorsToOwn(const base::PlatformFile* buffer, |
+ unsigned count) { |
+ DCHECK(count <= kMaxDescriptorsPerMessage); |
+ DCHECK_EQ(num_descriptors(), 0u); |
+ DCHECK_EQ(consumed_descriptor_highwater_, 0u); |
+ |
+ attachments_.reserve(count); |
+ for (unsigned i = 0; i < count; ++i) |
+ AddAttachment( |
+ new internal::PlatformFileAttachment(base::ScopedFD(buffer[i]))); |
+} |
+ |
+#endif // OS_POSIX |
+ |
} // namespace IPC |
+ |
+ |