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

Side by Side Diff: chrome/nacl/nacl_ipc_adapter.cc

Issue 10815087: Change NaClIPCAdapter to save translated descriptors to the rewritten message. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 5 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 | « chrome/nacl/nacl_ipc_adapter.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/nacl/nacl_ipc_adapter.h" 5 #include "chrome/nacl/nacl_ipc_adapter.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <string.h> 8 #include <string.h>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 class NaClIPCAdapter::RewrittenMessage 134 class NaClIPCAdapter::RewrittenMessage
135 : public base::RefCounted<RewrittenMessage> { 135 : public base::RefCounted<RewrittenMessage> {
136 public: 136 public:
137 RewrittenMessage(); 137 RewrittenMessage();
138 138
139 bool is_consumed() const { return data_read_cursor_ == data_len_; } 139 bool is_consumed() const { return data_read_cursor_ == data_len_; }
140 140
141 void SetData(const NaClIPCAdapter::NaClMessageHeader& header, 141 void SetData(const NaClIPCAdapter::NaClMessageHeader& header,
142 const void* payload, size_t payload_length); 142 const void* payload, size_t payload_length);
143 143
144 int Read(char* dest_buffer, size_t dest_buffer_size); 144 int Read(NaClImcTypedMsgHdr* msg);
145
146 void AddDescriptor(nacl::DescWrapper* desc) { descs_.push_back(desc); }
147
148 size_t desc_count() const { return descs_.size(); }
145 149
146 private: 150 private:
147 friend class base::RefCounted<RewrittenMessage>; 151 friend class base::RefCounted<RewrittenMessage>;
148 ~RewrittenMessage() {} 152 ~RewrittenMessage() {}
149 153
150 scoped_array<char> data_; 154 scoped_array<char> data_;
151 size_t data_len_; 155 size_t data_len_;
152 156
153 // Offset into data where the next read will happen. This will be equal to 157 // Offset into data where the next read will happen. This will be equal to
154 // data_len_ when all data has been consumed. 158 // data_len_ when all data has been consumed.
155 size_t data_read_cursor_; 159 size_t data_read_cursor_;
160
161 // Wrapped descriptors for transfer to untrusted code.
162 ScopedVector<nacl::DescWrapper> descs_;
156 }; 163 };
157 164
158 NaClIPCAdapter::RewrittenMessage::RewrittenMessage() 165 NaClIPCAdapter::RewrittenMessage::RewrittenMessage()
159 : data_len_(0), 166 : data_len_(0),
160 data_read_cursor_(0) { 167 data_read_cursor_(0) {
161 } 168 }
162 169
163 void NaClIPCAdapter::RewrittenMessage::SetData( 170 void NaClIPCAdapter::RewrittenMessage::SetData(
164 const NaClIPCAdapter::NaClMessageHeader& header, 171 const NaClIPCAdapter::NaClMessageHeader& header,
165 const void* payload, 172 const void* payload,
166 size_t payload_length) { 173 size_t payload_length) {
167 DCHECK(!data_.get() && data_len_ == 0); 174 DCHECK(!data_.get() && data_len_ == 0);
168 size_t header_len = sizeof(NaClIPCAdapter::NaClMessageHeader); 175 size_t header_len = sizeof(NaClIPCAdapter::NaClMessageHeader);
169 data_len_ = header_len + payload_length; 176 data_len_ = header_len + payload_length;
170 data_.reset(new char[data_len_]); 177 data_.reset(new char[data_len_]);
171 178
172 memcpy(data_.get(), &header, sizeof(NaClIPCAdapter::NaClMessageHeader)); 179 memcpy(data_.get(), &header, sizeof(NaClIPCAdapter::NaClMessageHeader));
173 memcpy(&data_[header_len], payload, payload_length); 180 memcpy(&data_[header_len], payload, payload_length);
174 } 181 }
175 182
176 int NaClIPCAdapter::RewrittenMessage::Read(char* dest_buffer, 183 int NaClIPCAdapter::RewrittenMessage::Read(NaClImcTypedMsgHdr* msg) {
177 size_t dest_buffer_size) {
178 CHECK(data_len_ >= data_read_cursor_); 184 CHECK(data_len_ >= data_read_cursor_);
185 char* dest_buffer = static_cast<char*>(msg->iov[0].base);
186 size_t dest_buffer_size = msg->iov[0].length;
179 size_t bytes_to_write = std::min(dest_buffer_size, 187 size_t bytes_to_write = std::min(dest_buffer_size,
180 data_len_ - data_read_cursor_); 188 data_len_ - data_read_cursor_);
181 if (bytes_to_write == 0) 189 if (bytes_to_write == 0)
182 return 0; 190 return 0;
183 191
184 memcpy(dest_buffer, &data_[data_read_cursor_], bytes_to_write); 192 memcpy(dest_buffer, &data_[data_read_cursor_], bytes_to_write);
185 data_read_cursor_ += bytes_to_write; 193 data_read_cursor_ += bytes_to_write;
194
195 // Once all data has been consumed, transfer any file descriptors.
196 if (is_consumed()) {
197 nacl_abi_size_t desc_count = static_cast<nacl_abi_size_t>(descs_.size());
198 CHECK(desc_count <= msg->ndesc_length);
199 msg->ndesc_length = desc_count;
200 for (nacl_abi_size_t i = 0; i < desc_count; i++) {
201 // Copy the NaClDesc to the buffer and add a ref so it won't be freed
202 // when we clear our ScopedVector.
203 msg->ndescv[i] = descs_[i]->desc();
204 NaClDescRef(descs_[i]->desc());
205 }
206 descs_.clear();
207 }
186 return static_cast<int>(bytes_to_write); 208 return static_cast<int>(bytes_to_write);
187 } 209 }
188 210
189 NaClIPCAdapter::LockedData::LockedData() 211 NaClIPCAdapter::LockedData::LockedData()
190 : channel_closed_(false) { 212 : channel_closed_(false) {
191 } 213 }
192 214
193 NaClIPCAdapter::LockedData::~LockedData() { 215 NaClIPCAdapter::LockedData::~LockedData() {
194 } 216 }
195 217
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 // When the plugin gives us too much data, it's an error. 309 // When the plugin gives us too much data, it's an error.
288 ClearToBeSent(); 310 ClearToBeSent();
289 return -1; 311 return -1;
290 } 312 }
291 } 313 }
292 314
293 int NaClIPCAdapter::BlockingReceive(NaClImcTypedMsgHdr* msg) { 315 int NaClIPCAdapter::BlockingReceive(NaClImcTypedMsgHdr* msg) {
294 if (msg->iov_length != 1) 316 if (msg->iov_length != 1)
295 return -1; 317 return -1;
296 318
297 char* output_buffer = static_cast<char*>(msg->iov[0].base);
298 size_t output_buffer_size = msg->iov[0].length;
299 int retval = 0; 319 int retval = 0;
300 { 320 {
301 base::AutoLock lock(lock_); 321 base::AutoLock lock(lock_);
302 while (locked_data_.to_be_received_.empty() && 322 while (locked_data_.to_be_received_.empty() &&
303 !locked_data_.channel_closed_) 323 !locked_data_.channel_closed_)
304 cond_var_.Wait(); 324 cond_var_.Wait();
305 if (locked_data_.channel_closed_) { 325 if (locked_data_.channel_closed_) {
306 retval = -1; 326 retval = -1;
307 } else { 327 } else {
308 retval = LockedReceive(output_buffer, output_buffer_size); 328 retval = LockedReceive(msg);
309 DCHECK(retval > 0); 329 DCHECK(retval > 0);
310 } 330 }
311 int desc_count = static_cast<int>(locked_data_.nacl_descs_.size());
312 CHECK(desc_count <= NACL_ABI_IMC_DESC_MAX);
313 msg->ndesc_length = desc_count;
314 for (int i = 0; i < desc_count; i++)
315 msg->ndescv[i] = locked_data_.nacl_descs_[i]->desc();
316 } 331 }
317 cond_var_.Signal(); 332 cond_var_.Signal();
318 return retval; 333 return retval;
319 } 334 }
320 335
321 void NaClIPCAdapter::CloseChannel() { 336 void NaClIPCAdapter::CloseChannel() {
322 { 337 {
323 base::AutoLock lock(lock_); 338 base::AutoLock lock(lock_);
324 locked_data_.channel_closed_ = true; 339 locked_data_.channel_closed_ = true;
325 } 340 }
326 cond_var_.Signal(); 341 cond_var_.Signal();
327 342
328 task_runner_->PostTask(FROM_HERE, 343 task_runner_->PostTask(FROM_HERE,
329 base::Bind(&NaClIPCAdapter::CloseChannelOnIOThread, this)); 344 base::Bind(&NaClIPCAdapter::CloseChannelOnIOThread, this));
330 } 345 }
331 346
332 NaClDesc* NaClIPCAdapter::MakeNaClDesc() { 347 NaClDesc* NaClIPCAdapter::MakeNaClDesc() {
333 return MakeNaClDescCustom(this); 348 return MakeNaClDescCustom(this);
334 } 349 }
335 350
336 #if defined(OS_POSIX) 351 #if defined(OS_POSIX)
337 int NaClIPCAdapter::TakeClientFileDescriptor() { 352 int NaClIPCAdapter::TakeClientFileDescriptor() {
338 return io_thread_data_.channel_->TakeClientFileDescriptor(); 353 return io_thread_data_.channel_->TakeClientFileDescriptor();
339 } 354 }
340 #endif 355 #endif
341 356
342 bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& message) { 357 bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& msg) {
343 { 358 {
344 base::AutoLock lock(lock_); 359 base::AutoLock lock(lock_);
345 360
346 // Clear any descriptors left from the prior message. 361 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
347 locked_data_.nacl_descs_.clear();
348 362
349 PickleIterator it(message); 363 PickleIterator it(msg);
350 switch (message.type()) { 364 switch (msg.type()) {
351 case PpapiMsg_PPBAudio_NotifyAudioStreamCreated::ID: { 365 case PpapiMsg_PPBAudio_NotifyAudioStreamCreated::ID: {
352 int instance_id; 366 int instance_id;
353 int resource_id; 367 int resource_id;
354 int result_code; 368 int result_code;
355 NaClHandle sock_handle; 369 NaClHandle sock_handle;
356 NaClHandle shm_handle; 370 NaClHandle shm_handle;
357 uint32_t shm_length; 371 uint32_t shm_length;
358 if (ReadHostResource(&it, &instance_id, &resource_id) && 372 if (ReadHostResource(&it, &instance_id, &resource_id) &&
359 it.ReadInt(&result_code) && 373 it.ReadInt(&result_code) &&
360 ReadFileDescriptor(message, &it, &sock_handle) && 374 ReadFileDescriptor(msg, &it, &sock_handle) &&
361 ReadFileDescriptor(message, &it, &shm_handle) && 375 ReadFileDescriptor(msg, &it, &shm_handle) &&
362 it.ReadUInt32(&shm_length)) { 376 it.ReadUInt32(&shm_length)) {
363 // Our caller, OnMessageReceived, holds the lock for locked_data_. 377 // Import the sync socket.
364 // Import the sync socket. Use DescWrappers to simplify clean up.
365 nacl::DescWrapperFactory factory; 378 nacl::DescWrapperFactory factory;
366 scoped_ptr<nacl::DescWrapper> socket_wrapper( 379 scoped_ptr<nacl::DescWrapper> socket_wrapper(
367 factory.ImportSyncSocketHandle(sock_handle)); 380 factory.ImportSyncSocketHandle(sock_handle));
368 // Import the shared memory handle and increase its size by 4 bytes to 381 // Import the shared memory handle and increase its size by 4 bytes to
369 // accommodate the length data we write to signal the host. 382 // accommodate the length data we write at the end to signal the host.
370 scoped_ptr<nacl::DescWrapper> shm_wrapper( 383 scoped_ptr<nacl::DescWrapper> shm_wrapper(
371 factory.ImportShmHandle(shm_handle, shm_length + sizeof(uint32))); 384 factory.ImportShmHandle(shm_handle, shm_length + sizeof(uint32)));
372 if (shm_wrapper.get() && socket_wrapper.get()) { 385 if (shm_wrapper.get() && socket_wrapper.get()) {
373 locked_data_.nacl_descs_.push_back(socket_wrapper.release()); 386 rewritten_msg->AddDescriptor(socket_wrapper.release());
374 locked_data_.nacl_descs_.push_back(shm_wrapper.release()); 387 rewritten_msg->AddDescriptor(shm_wrapper.release());
375 } 388 }
376 #if defined(OS_POSIX) 389 #if defined(OS_POSIX)
377 SaveMessage(message); 390 SaveMessage(msg, rewritten_msg.get());
378 #else // defined(OS_POSIX) 391 #else
379 // On Windows we must rewrite the message to the POSIX representation. 392 // On Windows we must rewrite the message to match the POSIX form.
380 IPC::Message new_msg(message.routing_id(), 393 IPC::Message new_msg(msg.routing_id(),
381 PpapiMsg_PPBAudio_NotifyAudioStreamCreated::ID, 394 PpapiMsg_PPBAudio_NotifyAudioStreamCreated::ID,
382 message.priority()); 395 msg.priority());
383 WriteHostResource(&new_msg, instance_id, resource_id); 396 WriteHostResource(&new_msg, instance_id, resource_id);
384 new_msg.WriteInt(result_code); 397 new_msg.WriteInt(result_code);
385 WriteFileDescriptor(&new_msg, 0); // socket handle, index = 0 398 WriteFileDescriptor(&new_msg, 0); // socket handle, index = 0
386 WriteFileDescriptor(&new_msg, 1); // shm handle, index = 1 399 WriteFileDescriptor(&new_msg, 1); // shm handle, index = 1
387 new_msg.WriteUInt32(shm_length); 400 new_msg.WriteUInt32(shm_length);
388 SaveMessage(new_msg); 401 SaveMessage(new_msg, rewritten_msg.get());
389 #endif 402 #endif
390 } 403 }
391 break; 404 break;
392 } 405 }
393 default: { 406 default: {
394 SaveMessage(message); 407 SaveMessage(msg, rewritten_msg.get());
395 } 408 }
396 } 409 }
397 } 410 }
398 cond_var_.Signal(); 411 cond_var_.Signal();
399 return true; 412 return true;
400 } 413 }
401 414
402 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) { 415 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) {
403 } 416 }
404 417
405 void NaClIPCAdapter::OnChannelError() { 418 void NaClIPCAdapter::OnChannelError() {
406 CloseChannel(); 419 CloseChannel();
407 } 420 }
408 421
409 NaClIPCAdapter::~NaClIPCAdapter() { 422 NaClIPCAdapter::~NaClIPCAdapter() {
410 // Make sure the channel is deleted on the IO thread. 423 // Make sure the channel is deleted on the IO thread.
411 task_runner_->PostTask(FROM_HERE, 424 task_runner_->PostTask(FROM_HERE,
412 base::Bind(&DeleteChannel, io_thread_data_.channel_.release())); 425 base::Bind(&DeleteChannel, io_thread_data_.channel_.release()));
413 } 426 }
414 427
415 int NaClIPCAdapter::LockedReceive(char* output_buffer, 428 int NaClIPCAdapter::LockedReceive(NaClImcTypedMsgHdr* msg) {
416 size_t output_buffer_size) {
417 lock_.AssertAcquired(); 429 lock_.AssertAcquired();
418 430
419 if (locked_data_.to_be_received_.empty()) 431 if (locked_data_.to_be_received_.empty())
420 return 0; 432 return 0;
421 scoped_refptr<RewrittenMessage> current = 433 scoped_refptr<RewrittenMessage> current =
422 locked_data_.to_be_received_.front(); 434 locked_data_.to_be_received_.front();
423 435
424 int retval = current->Read(output_buffer, output_buffer_size); 436 int retval = current->Read(msg);
425 437
426 // When a message is entirely consumed, remove if from the waiting queue. 438 // When a message is entirely consumed, remove if from the waiting queue.
427 if (current->is_consumed()) 439 if (current->is_consumed())
428 locked_data_.to_be_received_.pop(); 440 locked_data_.to_be_received_.pop();
441
429 return retval; 442 return retval;
430 } 443 }
431 444
432 bool NaClIPCAdapter::SendCompleteMessage(const char* buffer, 445 bool NaClIPCAdapter::SendCompleteMessage(const char* buffer,
433 size_t buffer_len) { 446 size_t buffer_len) {
434 // The message will have already been validated, so we know it's large enough 447 // The message will have already been validated, so we know it's large enough
435 // for our header. 448 // for our header.
436 const NaClMessageHeader* header = 449 const NaClMessageHeader* header =
437 reinterpret_cast<const NaClMessageHeader*>(buffer); 450 reinterpret_cast<const NaClMessageHeader*>(buffer);
438 451
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 } 501 }
489 502
490 void NaClIPCAdapter::CloseChannelOnIOThread() { 503 void NaClIPCAdapter::CloseChannelOnIOThread() {
491 io_thread_data_.channel_->Close(); 504 io_thread_data_.channel_->Close();
492 } 505 }
493 506
494 void NaClIPCAdapter::SendMessageOnIOThread(scoped_ptr<IPC::Message> message) { 507 void NaClIPCAdapter::SendMessageOnIOThread(scoped_ptr<IPC::Message> message) {
495 io_thread_data_.channel_->Send(message.release()); 508 io_thread_data_.channel_->Send(message.release());
496 } 509 }
497 510
498 void NaClIPCAdapter::SaveMessage(const IPC::Message& message) { 511 void NaClIPCAdapter::SaveMessage(const IPC::Message& msg,
512 RewrittenMessage* rewritten_msg) {
513 lock_.AssertAcquired();
499 // There is some padding in this structure (the "padding" member is 16 514 // There is some padding in this structure (the "padding" member is 16
500 // bits but this then gets padded to 32 bits). We want to be sure not to 515 // bits but this then gets padded to 32 bits). We want to be sure not to
501 // leak data to the untrusted plugin, so zero everything out first. 516 // leak data to the untrusted plugin, so zero everything out first.
502 NaClMessageHeader header; 517 NaClMessageHeader header;
503 memset(&header, 0, sizeof(NaClMessageHeader)); 518 memset(&header, 0, sizeof(NaClMessageHeader));
504 519
505 header.payload_size = static_cast<uint32>(message.payload_size()); 520 header.payload_size = static_cast<uint32>(msg.payload_size());
506 header.routing = message.routing_id(); 521 header.routing = msg.routing_id();
507 header.type = message.type(); 522 header.type = msg.type();
508 header.flags = message.flags(); 523 header.flags = msg.flags();
509 header.num_fds = static_cast<int>(locked_data_.nacl_descs_.size()); 524 header.num_fds = static_cast<int>(rewritten_msg->desc_count());
510 525
511 scoped_refptr<RewrittenMessage> dest(new RewrittenMessage); 526 rewritten_msg->SetData(header, msg.payload(), msg.payload_size());
512 dest->SetData(header, message.payload(), message.payload_size()); 527 locked_data_.to_be_received_.push(rewritten_msg);
513 locked_data_.to_be_received_.push(dest);
514 } 528 }
515 529
OLDNEW
« no previous file with comments | « chrome/nacl/nacl_ipc_adapter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698