| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/edk/system/transport_data.h" | 5 #include "mojo/edk/system/transport_data.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 current_offset = MessageInTransit::RoundUpMessageAlignment(current_offset); | 184 current_offset = MessageInTransit::RoundUpMessageAlignment(current_offset); |
| 185 } | 185 } |
| 186 | 186 |
| 187 // There's no aligned realloc, so it's no good way to release unused space (if | 187 // There's no aligned realloc, so it's no good way to release unused space (if |
| 188 // we overshot our estimated space requirements). | 188 // we overshot our estimated space requirements). |
| 189 buffer_size_ = current_offset; | 189 buffer_size_ = current_offset; |
| 190 | 190 |
| 191 // |dispatchers_| will be destroyed as it goes out of scope. | 191 // |dispatchers_| will be destroyed as it goes out of scope. |
| 192 } | 192 } |
| 193 | 193 |
| 194 #if defined(OS_POSIX) | |
| 195 TransportData::TransportData( | 194 TransportData::TransportData( |
| 196 embedder::ScopedPlatformHandleVectorPtr platform_handles) | 195 embedder::ScopedPlatformHandleVectorPtr platform_handles) |
| 197 : buffer_size_(sizeof(Header)), platform_handles_(platform_handles.Pass()) { | 196 : buffer_size_(sizeof(Header)), platform_handles_(platform_handles.Pass()) { |
| 198 buffer_.reset(static_cast<char*>( | 197 buffer_.reset(static_cast<char*>( |
| 199 base::AlignedAlloc(buffer_size_, MessageInTransit::kMessageAlignment))); | 198 base::AlignedAlloc(buffer_size_, MessageInTransit::kMessageAlignment))); |
| 200 memset(buffer_.get(), 0, buffer_size_); | 199 memset(buffer_.get(), 0, buffer_size_); |
| 200 |
| 201 Header* header = reinterpret_cast<Header*>(buffer_.get()); |
| 202 header->num_platform_handles = |
| 203 static_cast<uint32_t>(platform_handles_->size()); |
| 201 } | 204 } |
| 202 #endif // defined(OS_POSIX) | |
| 203 | 205 |
| 204 TransportData::~TransportData() { | 206 TransportData::~TransportData() { |
| 205 } | 207 } |
| 206 | 208 |
| 207 // static | 209 // static |
| 208 const char* TransportData::ValidateBuffer( | 210 const char* TransportData::ValidateBuffer( |
| 209 size_t serialized_platform_handle_size, | 211 size_t serialized_platform_handle_size, |
| 210 const void* buffer, | 212 const void* buffer, |
| 211 size_t buffer_size) { | 213 size_t buffer_size) { |
| 212 DCHECK(buffer); | 214 DCHECK(buffer); |
| 213 DCHECK_GT(buffer_size, 0u); | 215 DCHECK_GT(buffer_size, 0u); |
| 214 | 216 |
| 215 // Always make sure that the buffer size is sane; if it's not, someone's | 217 // Always make sure that the buffer size is sane; if it's not, someone's |
| 216 // messing with us. | 218 // messing with us. |
| 217 if (buffer_size < sizeof(Header) || buffer_size > GetMaxBufferSize() || | 219 if (buffer_size < sizeof(Header) || buffer_size > GetMaxBufferSize() || |
| 218 buffer_size % MessageInTransit::kMessageAlignment != 0) | 220 buffer_size % MessageInTransit::kMessageAlignment != 0) |
| 219 return "Invalid message secondary buffer size"; | 221 return "Invalid message secondary buffer size"; |
| 220 | 222 |
| 221 const Header* header = static_cast<const Header*>(buffer); | 223 const Header* header = static_cast<const Header*>(buffer); |
| 222 const size_t num_handles = header->num_handles; | 224 const size_t num_handles = header->num_handles; |
| 223 | 225 |
| 224 #if !defined(OS_POSIX) | |
| 225 // On POSIX, we send control messages with platform handles (but no handles) | |
| 226 // attached (see the comments for | |
| 227 // |TransportData(embedder::ScopedPlatformHandleVectorPtr)|. (This check isn't | |
| 228 // important security-wise anyway.) | |
| 229 if (num_handles == 0) | |
| 230 return "Message has no handles attached, but secondary buffer present"; | |
| 231 #endif | |
| 232 | |
| 233 // Sanity-check |num_handles| (before multiplying it against anything). | 226 // Sanity-check |num_handles| (before multiplying it against anything). |
| 234 if (num_handles > GetConfiguration().max_message_num_handles) | 227 if (num_handles > GetConfiguration().max_message_num_handles) |
| 235 return "Message handle payload too large"; | 228 return "Message handle payload too large"; |
| 236 | 229 |
| 237 if (buffer_size < sizeof(Header) + num_handles * sizeof(HandleTableEntry)) | 230 if (buffer_size < sizeof(Header) + num_handles * sizeof(HandleTableEntry)) |
| 238 return "Message secondary buffer too small"; | 231 return "Message secondary buffer too small"; |
| 239 | 232 |
| 240 if (header->num_platform_handles == 0) { | 233 if (header->num_platform_handles == 0) { |
| 241 // Then |platform_handle_table_offset| should also be zero. | 234 // Then |platform_handle_table_offset| should also be zero. |
| 242 if (header->platform_handle_table_offset != 0) { | 235 if (header->platform_handle_table_offset != 0) { |
| 243 return "Message has no handles attached, but platform handle table " | 236 return "Message has no handles attached, but platform handle table " |
| 244 "present"; | 237 "present"; |
| 245 } | 238 } |
| 246 } else { | 239 } else { |
| 247 // |num_handles| has already been validated, so the multiplication is okay. | |
| 248 if (header->num_platform_handles > | 240 if (header->num_platform_handles > |
| 249 num_handles * kMaxSerializedDispatcherPlatformHandles) | 241 GetConfiguration().max_message_num_handles * |
| 242 kMaxSerializedDispatcherPlatformHandles) |
| 250 return "Message has too many platform handles attached"; | 243 return "Message has too many platform handles attached"; |
| 251 | 244 |
| 252 static const char kInvalidPlatformHandleTableOffset[] = | 245 static const char kInvalidPlatformHandleTableOffset[] = |
| 253 "Message has invalid platform handle table offset"; | 246 "Message has invalid platform handle table offset"; |
| 254 // This doesn't check that the platform handle table doesn't alias other | 247 // This doesn't check that the platform handle table doesn't alias other |
| 255 // stuff, but it doesn't matter, since it's all read-only. | 248 // stuff, but it doesn't matter, since it's all read-only. |
| 256 if (header->platform_handle_table_offset % | 249 if (header->platform_handle_table_offset % |
| 257 MessageInTransit::kMessageAlignment != | 250 MessageInTransit::kMessageAlignment != |
| 258 0) | 251 0) |
| 259 return kInvalidPlatformHandleTableOffset; | 252 return kInvalidPlatformHandleTableOffset; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 const void* source = static_cast<const char*>(buffer) + offset; | 328 const void* source = static_cast<const char*>(buffer) + offset; |
| 336 (*dispatchers)[i] = Dispatcher::TransportDataAccess::Deserialize( | 329 (*dispatchers)[i] = Dispatcher::TransportDataAccess::Deserialize( |
| 337 channel, handle_table[i].type, source, size, platform_handles.get()); | 330 channel, handle_table[i].type, source, size, platform_handles.get()); |
| 338 } | 331 } |
| 339 | 332 |
| 340 return dispatchers.Pass(); | 333 return dispatchers.Pass(); |
| 341 } | 334 } |
| 342 | 335 |
| 343 } // namespace system | 336 } // namespace system |
| 344 } // namespace mojo | 337 } // namespace mojo |
| OLD | NEW |