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

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

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