Index: mojo/edk/system/shared_buffer_dispatcher.cc |
diff --git a/mojo/edk/system/shared_buffer_dispatcher.cc b/mojo/edk/system/shared_buffer_dispatcher.cc |
index 4c548e0c0e81497a4c8b3e19edf55af431b1094a..d531989c1032aa44d495a3fd4ed0db750414096b 100644 |
--- a/mojo/edk/system/shared_buffer_dispatcher.cc |
+++ b/mojo/edk/system/shared_buffer_dispatcher.cc |
@@ -26,8 +26,12 @@ namespace { |
struct SerializedState { |
uint64_t num_bytes; |
+ uint32_t flags; |
+ uint32_t padding; |
}; |
+const uint32_t kSerializedStateFlagsReadOnly = 1 << 0; |
+ |
#pragma pack(pop) |
static_assert(sizeof(SerializedState) % 8 == 0, |
@@ -141,9 +145,10 @@ scoped_refptr<SharedBufferDispatcher> SharedBufferDispatcher::Deserialize( |
// Wrapping |platform_handle| in a |ScopedPlatformHandle| means that it'll be |
// closed even if creation fails. |
+ bool read_only = (serialization->flags & kSerializedStateFlagsReadOnly); |
scoped_refptr<PlatformSharedBuffer> shared_buffer( |
PlatformSharedBuffer::CreateFromPlatformHandle( |
- static_cast<size_t>(serialization->num_bytes), |
+ static_cast<size_t>(serialization->num_bytes), read_only, |
ScopedPlatformHandle(platform_handle))); |
if (!shared_buffer) { |
LOG(ERROR) |
@@ -190,6 +195,21 @@ MojoResult SharedBufferDispatcher::DuplicateBufferHandle( |
base::AutoLock lock(lock_); |
if (in_transit_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
+ |
+ if ((validated_options.flags & |
+ MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_READ_ONLY) && |
+ (!shared_buffer_->IsReadOnly())) { |
+ // If a read-only duplicate is requested and |shared_buffer_| is not |
+ // read-only, make a read-only duplicate of |shared_buffer_|. |
+ scoped_refptr<PlatformSharedBuffer> read_only_buffer = |
+ shared_buffer_->CreateReadOnlyDuplicate(); |
+ if (!read_only_buffer) |
+ return MOJO_RESULT_FAILED_PRECONDITION; |
+ DCHECK(read_only_buffer->IsReadOnly()); |
+ *new_dispatcher = CreateInternal(std::move(read_only_buffer)); |
+ return MOJO_RESULT_OK; |
+ } |
+ |
*new_dispatcher = CreateInternal(shared_buffer_); |
return MOJO_RESULT_OK; |
} |
@@ -215,8 +235,10 @@ MojoResult SharedBufferDispatcher::MapBuffer( |
DCHECK(mapping); |
*mapping = shared_buffer_->MapNoCheck(static_cast<size_t>(offset), |
static_cast<size_t>(num_bytes)); |
- if (!*mapping) |
+ if (!*mapping) { |
+ LOG(ERROR) << "Unable to map: read_only" << shared_buffer_->IsReadOnly(); |
return MOJO_RESULT_RESOURCE_EXHAUSTED; |
+ } |
return MOJO_RESULT_OK; |
} |
@@ -237,6 +259,9 @@ bool SharedBufferDispatcher::EndSerialize(void* destination, |
base::AutoLock lock(lock_); |
serialization->num_bytes = |
static_cast<uint64_t>(shared_buffer_->GetNumBytes()); |
+ serialization->flags = |
+ (shared_buffer_->IsReadOnly() ? kSerializedStateFlagsReadOnly : 0); |
+ serialization->padding = 0; |
handle_for_transit_ = shared_buffer_->DuplicatePlatformHandle(); |
if (!handle_for_transit_.is_valid()) { |
@@ -283,7 +308,7 @@ MojoResult SharedBufferDispatcher::ValidateDuplicateOptions( |
const MojoDuplicateBufferHandleOptions* in_options, |
MojoDuplicateBufferHandleOptions* out_options) { |
const MojoDuplicateBufferHandleOptionsFlags kKnownFlags = |
- MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE; |
+ MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_READ_ONLY; |
static const MojoDuplicateBufferHandleOptions kDefaultOptions = { |
static_cast<uint32_t>(sizeof(MojoDuplicateBufferHandleOptions)), |
MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE}; |