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 |