Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: mojo/system/core.cc

Issue 304303006: Mojo: Specify/check alignment of pointers more carefully. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix msvs Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « mojo/mojo.gyp ('k') | mojo/system/core_test_base.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/system/core.h" 5 #include "mojo/system/core.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/time/time.h" 10 #include "base/time/time.h"
11 #include "mojo/public/c/system/macros.h"
11 #include "mojo/system/constants.h" 12 #include "mojo/system/constants.h"
12 #include "mojo/system/data_pipe.h" 13 #include "mojo/system/data_pipe.h"
13 #include "mojo/system/data_pipe_consumer_dispatcher.h" 14 #include "mojo/system/data_pipe_consumer_dispatcher.h"
14 #include "mojo/system/data_pipe_producer_dispatcher.h" 15 #include "mojo/system/data_pipe_producer_dispatcher.h"
15 #include "mojo/system/dispatcher.h" 16 #include "mojo/system/dispatcher.h"
16 #include "mojo/system/local_data_pipe.h" 17 #include "mojo/system/local_data_pipe.h"
17 #include "mojo/system/memory.h" 18 #include "mojo/system/memory.h"
18 #include "mojo/system/message_pipe.h" 19 #include "mojo/system/message_pipe.h"
19 #include "mojo/system/message_pipe_dispatcher.h" 20 #include "mojo/system/message_pipe_dispatcher.h"
20 #include "mojo/system/raw_shared_buffer.h" 21 #include "mojo/system/raw_shared_buffer.h"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 MojoResult Core::Wait(MojoHandle handle, 120 MojoResult Core::Wait(MojoHandle handle,
120 MojoWaitFlags flags, 121 MojoWaitFlags flags,
121 MojoDeadline deadline) { 122 MojoDeadline deadline) {
122 return WaitManyInternal(&handle, &flags, 1, deadline); 123 return WaitManyInternal(&handle, &flags, 1, deadline);
123 } 124 }
124 125
125 MojoResult Core::WaitMany(const MojoHandle* handles, 126 MojoResult Core::WaitMany(const MojoHandle* handles,
126 const MojoWaitFlags* flags, 127 const MojoWaitFlags* flags,
127 uint32_t num_handles, 128 uint32_t num_handles,
128 MojoDeadline deadline) { 129 MojoDeadline deadline) {
129 if (!VerifyUserPointer<MojoHandle>(handles, num_handles)) 130 if (!VerifyUserPointerWithCount<MojoHandle>(handles, num_handles))
130 return MOJO_RESULT_INVALID_ARGUMENT; 131 return MOJO_RESULT_INVALID_ARGUMENT;
131 if (!VerifyUserPointer<MojoWaitFlags>(flags, num_handles)) 132 if (!VerifyUserPointerWithCount<MojoWaitFlags>(flags, num_handles))
132 return MOJO_RESULT_INVALID_ARGUMENT; 133 return MOJO_RESULT_INVALID_ARGUMENT;
133 if (num_handles < 1) 134 if (num_handles < 1)
134 return MOJO_RESULT_INVALID_ARGUMENT; 135 return MOJO_RESULT_INVALID_ARGUMENT;
135 if (num_handles > kMaxWaitManyNumHandles) 136 if (num_handles > kMaxWaitManyNumHandles)
136 return MOJO_RESULT_RESOURCE_EXHAUSTED; 137 return MOJO_RESULT_RESOURCE_EXHAUSTED;
137 return WaitManyInternal(handles, flags, num_handles, deadline); 138 return WaitManyInternal(handles, flags, num_handles, deadline);
138 } 139 }
139 140
140 MojoResult Core::CreateMessagePipe(MojoHandle* message_pipe_handle0, 141 MojoResult Core::CreateMessagePipe(MojoHandle* message_pipe_handle0,
141 MojoHandle* message_pipe_handle1) { 142 MojoHandle* message_pipe_handle1) {
142 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle0, 1)) 143 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle0))
143 return MOJO_RESULT_INVALID_ARGUMENT; 144 return MOJO_RESULT_INVALID_ARGUMENT;
144 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle1, 1)) 145 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle1))
145 return MOJO_RESULT_INVALID_ARGUMENT; 146 return MOJO_RESULT_INVALID_ARGUMENT;
146 147
147 scoped_refptr<MessagePipeDispatcher> dispatcher0(new MessagePipeDispatcher()); 148 scoped_refptr<MessagePipeDispatcher> dispatcher0(new MessagePipeDispatcher());
148 scoped_refptr<MessagePipeDispatcher> dispatcher1(new MessagePipeDispatcher()); 149 scoped_refptr<MessagePipeDispatcher> dispatcher1(new MessagePipeDispatcher());
149 150
150 std::pair<MojoHandle, MojoHandle> handle_pair; 151 std::pair<MojoHandle, MojoHandle> handle_pair;
151 { 152 {
152 base::AutoLock locker(handle_table_lock_); 153 base::AutoLock locker(handle_table_lock_);
153 handle_pair = handle_table_.AddDispatcherPair(dispatcher0, dispatcher1); 154 handle_pair = handle_table_.AddDispatcherPair(dispatcher0, dispatcher1);
154 } 155 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 return dispatcher->WriteMessage(bytes, num_bytes, NULL, flags); 192 return dispatcher->WriteMessage(bytes, num_bytes, NULL, flags);
192 193
193 // We have to handle |handles| here, since we have to mark them busy in the 194 // We have to handle |handles| here, since we have to mark them busy in the
194 // global handle table. We can't delegate this to the dispatcher, since the 195 // global handle table. We can't delegate this to the dispatcher, since the
195 // handle table lock must be acquired before the dispatcher lock. 196 // handle table lock must be acquired before the dispatcher lock.
196 // 197 //
197 // (This leads to an oddity: |handles|/|num_handles| are always verified for 198 // (This leads to an oddity: |handles|/|num_handles| are always verified for
198 // validity, even for dispatchers that don't support |WriteMessage()| and will 199 // validity, even for dispatchers that don't support |WriteMessage()| and will
199 // simply return failure unconditionally. It also breaks the usual 200 // simply return failure unconditionally. It also breaks the usual
200 // left-to-right verification order of arguments.) 201 // left-to-right verification order of arguments.)
201 if (!VerifyUserPointer<MojoHandle>(handles, num_handles)) 202 if (!VerifyUserPointerWithCount<MojoHandle>(handles, num_handles))
202 return MOJO_RESULT_INVALID_ARGUMENT; 203 return MOJO_RESULT_INVALID_ARGUMENT;
203 if (num_handles > kMaxMessageNumHandles) 204 if (num_handles > kMaxMessageNumHandles)
204 return MOJO_RESULT_RESOURCE_EXHAUSTED; 205 return MOJO_RESULT_RESOURCE_EXHAUSTED;
205 206
206 // We'll need to hold on to the dispatchers so that we can pass them on to 207 // We'll need to hold on to the dispatchers so that we can pass them on to
207 // |WriteMessage()| and also so that we can unlock their locks afterwards 208 // |WriteMessage()| and also so that we can unlock their locks afterwards
208 // without accessing the handle table. These can be dumb pointers, since their 209 // without accessing the handle table. These can be dumb pointers, since their
209 // entries in the handle table won't get removed (since they'll be marked as 210 // entries in the handle table won't get removed (since they'll be marked as
210 // busy). 211 // busy).
211 std::vector<DispatcherTransport> transports(num_handles); 212 std::vector<DispatcherTransport> transports(num_handles);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 void* bytes, 245 void* bytes,
245 uint32_t* num_bytes, 246 uint32_t* num_bytes,
246 MojoHandle* handles, 247 MojoHandle* handles,
247 uint32_t* num_handles, 248 uint32_t* num_handles,
248 MojoReadMessageFlags flags) { 249 MojoReadMessageFlags flags) {
249 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); 250 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle));
250 if (!dispatcher) 251 if (!dispatcher)
251 return MOJO_RESULT_INVALID_ARGUMENT; 252 return MOJO_RESULT_INVALID_ARGUMENT;
252 253
253 if (num_handles) { 254 if (num_handles) {
254 if (!VerifyUserPointer<uint32_t>(num_handles, 1)) 255 if (!VerifyUserPointer<uint32_t>(num_handles))
255 return MOJO_RESULT_INVALID_ARGUMENT; 256 return MOJO_RESULT_INVALID_ARGUMENT;
256 if (!VerifyUserPointer<MojoHandle>(handles, *num_handles)) 257 if (!VerifyUserPointerWithCount<MojoHandle>(handles, *num_handles))
257 return MOJO_RESULT_INVALID_ARGUMENT; 258 return MOJO_RESULT_INVALID_ARGUMENT;
258 } 259 }
259 260
260 // Easy case: won't receive any handles. 261 // Easy case: won't receive any handles.
261 if (!num_handles || *num_handles == 0) 262 if (!num_handles || *num_handles == 0)
262 return dispatcher->ReadMessage(bytes, num_bytes, NULL, num_handles, flags); 263 return dispatcher->ReadMessage(bytes, num_bytes, NULL, num_handles, flags);
263 264
264 DispatcherVector dispatchers; 265 DispatcherVector dispatchers;
265 MojoResult rv = dispatcher->ReadMessage(bytes, num_bytes, 266 MojoResult rv = dispatcher->ReadMessage(bytes, num_bytes,
266 &dispatchers, num_handles, 267 &dispatchers, num_handles,
(...skipping 20 matching lines...) Expand all
287 } 288 }
288 289
289 return rv; 290 return rv;
290 } 291 }
291 292
292 MojoResult Core::CreateDataPipe(const MojoCreateDataPipeOptions* options, 293 MojoResult Core::CreateDataPipe(const MojoCreateDataPipeOptions* options,
293 MojoHandle* data_pipe_producer_handle, 294 MojoHandle* data_pipe_producer_handle,
294 MojoHandle* data_pipe_consumer_handle) { 295 MojoHandle* data_pipe_consumer_handle) {
295 if (options) { 296 if (options) {
296 // The |struct_size| field must be valid to read. 297 // The |struct_size| field must be valid to read.
297 if (!VerifyUserPointer<uint32_t>(&options->struct_size, 1)) 298 if (!VerifyUserPointer<uint32_t>(&options->struct_size))
298 return MOJO_RESULT_INVALID_ARGUMENT; 299 return MOJO_RESULT_INVALID_ARGUMENT;
299 // And then |options| must point to at least |options->struct_size| bytes. 300 // And then |options| must point to at least |options->struct_size| bytes.
300 if (!VerifyUserPointer<void>(options, options->struct_size)) 301 if (!VerifyUserPointerWithSize<MOJO_ALIGNOF(int64_t)>(options,
302 options->struct_size))
301 return MOJO_RESULT_INVALID_ARGUMENT; 303 return MOJO_RESULT_INVALID_ARGUMENT;
302 } 304 }
303 if (!VerifyUserPointer<MojoHandle>(data_pipe_producer_handle, 1)) 305 if (!VerifyUserPointer<MojoHandle>(data_pipe_producer_handle))
304 return MOJO_RESULT_INVALID_ARGUMENT; 306 return MOJO_RESULT_INVALID_ARGUMENT;
305 if (!VerifyUserPointer<MojoHandle>(data_pipe_consumer_handle, 1)) 307 if (!VerifyUserPointer<MojoHandle>(data_pipe_consumer_handle))
306 return MOJO_RESULT_INVALID_ARGUMENT; 308 return MOJO_RESULT_INVALID_ARGUMENT;
307 309
308 MojoCreateDataPipeOptions validated_options = { 0 }; 310 MojoCreateDataPipeOptions validated_options = { 0 };
309 MojoResult result = DataPipe::ValidateOptions(options, &validated_options); 311 MojoResult result = DataPipe::ValidateOptions(options, &validated_options);
310 if (result != MOJO_RESULT_OK) 312 if (result != MOJO_RESULT_OK)
311 return result; 313 return result;
312 314
313 scoped_refptr<DataPipeProducerDispatcher> producer_dispatcher( 315 scoped_refptr<DataPipeProducerDispatcher> producer_dispatcher(
314 new DataPipeProducerDispatcher()); 316 new DataPipeProducerDispatcher());
315 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher( 317 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher(
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 408
407 return dispatcher->EndReadData(num_bytes_read); 409 return dispatcher->EndReadData(num_bytes_read);
408 } 410 }
409 411
410 MojoResult Core::CreateSharedBuffer( 412 MojoResult Core::CreateSharedBuffer(
411 const MojoCreateSharedBufferOptions* options, 413 const MojoCreateSharedBufferOptions* options,
412 uint64_t num_bytes, 414 uint64_t num_bytes,
413 MojoHandle* shared_buffer_handle) { 415 MojoHandle* shared_buffer_handle) {
414 if (options) { 416 if (options) {
415 // The |struct_size| field must be valid to read. 417 // The |struct_size| field must be valid to read.
416 if (!VerifyUserPointer<uint32_t>(&options->struct_size, 1)) 418 if (!VerifyUserPointer<uint32_t>(&options->struct_size))
417 return MOJO_RESULT_INVALID_ARGUMENT; 419 return MOJO_RESULT_INVALID_ARGUMENT;
418 // And then |options| must point to at least |options->struct_size| bytes. 420 // And then |options| must point to at least |options->struct_size| bytes.
419 if (!VerifyUserPointer<void>(options, options->struct_size)) 421 if (!VerifyUserPointerWithSize<MOJO_ALIGNOF(int64_t)>(options,
422 options->struct_size))
420 return MOJO_RESULT_INVALID_ARGUMENT; 423 return MOJO_RESULT_INVALID_ARGUMENT;
421 } 424 }
422 if (!VerifyUserPointer<MojoHandle>(shared_buffer_handle, 1)) 425 if (!VerifyUserPointer<MojoHandle>(shared_buffer_handle))
423 return MOJO_RESULT_INVALID_ARGUMENT; 426 return MOJO_RESULT_INVALID_ARGUMENT;
424 427
425 MojoCreateSharedBufferOptions validated_options = { 0 }; 428 MojoCreateSharedBufferOptions validated_options = { 0 };
426 MojoResult result = 429 MojoResult result =
427 SharedBufferDispatcher::ValidateOptions(options, &validated_options); 430 SharedBufferDispatcher::ValidateOptions(options, &validated_options);
428 if (result != MOJO_RESULT_OK) 431 if (result != MOJO_RESULT_OK)
429 return result; 432 return result;
430 433
431 scoped_refptr<SharedBufferDispatcher> dispatcher; 434 scoped_refptr<SharedBufferDispatcher> dispatcher;
432 result = SharedBufferDispatcher::Create(validated_options, num_bytes, 435 result = SharedBufferDispatcher::Create(validated_options, num_bytes,
(...skipping 16 matching lines...) Expand all
449 452
450 MojoResult Core::DuplicateBufferHandle( 453 MojoResult Core::DuplicateBufferHandle(
451 MojoHandle buffer_handle, 454 MojoHandle buffer_handle,
452 const MojoDuplicateBufferHandleOptions* options, 455 const MojoDuplicateBufferHandleOptions* options,
453 MojoHandle* new_buffer_handle) { 456 MojoHandle* new_buffer_handle) {
454 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); 457 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle));
455 if (!dispatcher) 458 if (!dispatcher)
456 return MOJO_RESULT_INVALID_ARGUMENT; 459 return MOJO_RESULT_INVALID_ARGUMENT;
457 460
458 // Don't verify |options| here; that's the dispatcher's job. 461 // Don't verify |options| here; that's the dispatcher's job.
459 if (!VerifyUserPointer<MojoHandle>(new_buffer_handle, 1)) 462 if (!VerifyUserPointer<MojoHandle>(new_buffer_handle))
460 return MOJO_RESULT_INVALID_ARGUMENT; 463 return MOJO_RESULT_INVALID_ARGUMENT;
461 464
462 scoped_refptr<Dispatcher> new_dispatcher; 465 scoped_refptr<Dispatcher> new_dispatcher;
463 MojoResult result = dispatcher->DuplicateBufferHandle(options, 466 MojoResult result = dispatcher->DuplicateBufferHandle(options,
464 &new_dispatcher); 467 &new_dispatcher);
465 if (result != MOJO_RESULT_OK) 468 if (result != MOJO_RESULT_OK)
466 return result; 469 return result;
467 470
468 MojoHandle new_handle = AddDispatcher(new_dispatcher); 471 MojoHandle new_handle = AddDispatcher(new_dispatcher);
469 if (new_handle == MOJO_HANDLE_INVALID) { 472 if (new_handle == MOJO_HANDLE_INVALID) {
470 LOG(ERROR) << "Handle table full"; 473 LOG(ERROR) << "Handle table full";
471 dispatcher->Close(); 474 dispatcher->Close();
472 return MOJO_RESULT_RESOURCE_EXHAUSTED; 475 return MOJO_RESULT_RESOURCE_EXHAUSTED;
473 } 476 }
474 477
475 *new_buffer_handle = new_handle; 478 *new_buffer_handle = new_handle;
476 return MOJO_RESULT_OK; 479 return MOJO_RESULT_OK;
477 } 480 }
478 481
479 MojoResult Core::MapBuffer(MojoHandle buffer_handle, 482 MojoResult Core::MapBuffer(MojoHandle buffer_handle,
480 uint64_t offset, 483 uint64_t offset,
481 uint64_t num_bytes, 484 uint64_t num_bytes,
482 void** buffer, 485 void** buffer,
483 MojoMapBufferFlags flags) { 486 MojoMapBufferFlags flags) {
484 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); 487 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle));
485 if (!dispatcher) 488 if (!dispatcher)
486 return MOJO_RESULT_INVALID_ARGUMENT; 489 return MOJO_RESULT_INVALID_ARGUMENT;
487 490
488 if (!VerifyUserPointer<void*>(buffer, 1)) 491 if (!VerifyUserPointerWithCount<void*>(buffer, 1))
489 return MOJO_RESULT_INVALID_ARGUMENT; 492 return MOJO_RESULT_INVALID_ARGUMENT;
490 493
491 scoped_ptr<RawSharedBufferMapping> mapping; 494 scoped_ptr<RawSharedBufferMapping> mapping;
492 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); 495 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping);
493 if (result != MOJO_RESULT_OK) 496 if (result != MOJO_RESULT_OK)
494 return result; 497 return result;
495 498
496 DCHECK(mapping); 499 DCHECK(mapping);
497 void* address = mapping->base(); 500 void* address = mapping->base();
498 { 501 {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be 557 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be
555 // destroyed, but this would still be required if the waiter were in TLS.) 558 // destroyed, but this would still be required if the waiter were in TLS.)
556 for (i = 0; i < num_added; i++) 559 for (i = 0; i < num_added; i++)
557 dispatchers[i]->RemoveWaiter(&waiter); 560 dispatchers[i]->RemoveWaiter(&waiter);
558 561
559 return rv; 562 return rv;
560 } 563 }
561 564
562 } // namespace system 565 } // namespace system
563 } // namespace mojo 566 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/mojo.gyp ('k') | mojo/system/core_test_base.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698