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

Side by Side Diff: chrome/browser/net/network_stats.cc

Issue 168203003: NetworkStats: fix use after free. Don't call socket_->Read if tests are (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: handle random packet being received before the test Created 6 years, 10 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/browser/net/network_stats.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 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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/browser/net/network_stats.h" 5 #include "chrome/browser/net/network_stats.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/field_trial.h" 10 #include "base/metrics/field_trial.h"
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 } 313 }
314 314
315 int NetworkStats::ReadData() { 315 int NetworkStats::ReadData() {
316 if (!socket_.get()) 316 if (!socket_.get())
317 return 0; 317 return 0;
318 318
319 if (read_state_ == READ_STATE_READ_PENDING) 319 if (read_state_ == READ_STATE_READ_PENDING)
320 return net::ERR_IO_PENDING; 320 return net::ERR_IO_PENDING;
321 321
322 int rv = 0; 322 int rv = 0;
323 do { 323 while (true) {
324 DCHECK(!read_buffer_.get()); 324 DCHECK(!read_buffer_.get());
325 read_buffer_ = new net::IOBuffer(kMaxMessageSize); 325 read_buffer_ = new net::IOBuffer(kMaxMessageSize);
326 326
327 rv = socket_->Read( 327 rv = socket_->Read(
328 read_buffer_.get(), 328 read_buffer_.get(),
329 kMaxMessageSize, 329 kMaxMessageSize,
330 base::Bind(&NetworkStats::OnReadComplete, weak_factory_.GetWeakPtr())); 330 base::Bind(&NetworkStats::OnReadComplete, weak_factory_.GetWeakPtr()));
331 } while (rv > 0 && !ReadComplete(rv)); 331 if (rv <= 0)
332 break;
333 if (ReadComplete(rv))
334 return rv;
335 };
332 if (rv == net::ERR_IO_PENDING) 336 if (rv == net::ERR_IO_PENDING)
333 read_state_ = READ_STATE_READ_PENDING; 337 read_state_ = READ_STATE_READ_PENDING;
334 return rv; 338 return rv;
335 } 339 }
336 340
337 void NetworkStats::OnReadComplete(int result) { 341 void NetworkStats::OnReadComplete(int result) {
338 DCHECK_NE(net::ERR_IO_PENDING, result); 342 DCHECK_NE(net::ERR_IO_PENDING, result);
339 DCHECK_EQ(READ_STATE_READ_PENDING, read_state_); 343 DCHECK_EQ(READ_STATE_READ_PENDING, read_state_);
340 344
341 read_state_ = READ_STATE_IDLE; 345 read_state_ = READ_STATE_IDLE;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 default: 391 default:
388 DVLOG(1) << "Received unexpected packet type: " 392 DVLOG(1) << "Received unexpected packet type: "
389 << probe_packet.header().type(); 393 << probe_packet.header().type();
390 } 394 }
391 395
392 if (!current_test_complete) { 396 if (!current_test_complete) {
393 // All packets have not been received for the current test. 397 // All packets have not been received for the current test.
394 return false; 398 return false;
395 } 399 }
396 // All packets are received for the current test. 400 // All packets are received for the current test.
397 // Read completes if all tests are done. 401 // Read completes if all tests are done (if TestPhaseComplete didn't start
398 bool all_tests_done = current_test_index_ >= maximum_tests_ || 402 // another test).
399 current_test_index_ + 1 >= test_sequence_.size(); 403 return TestPhaseComplete(SUCCESS, net::OK);
400 TestPhaseComplete(SUCCESS, net::OK);
401 return all_tests_done;
402 } 404 }
403 405
404 bool NetworkStats::UpdateReception(const ProbePacket& probe_packet) { 406 bool NetworkStats::UpdateReception(const ProbePacket& probe_packet) {
405 uint32 packet_index = probe_packet.packet_index(); 407 uint32 packet_index = probe_packet.packet_index();
406 if (packet_index >= packet_rtt_.size()) 408 if (packet_index >= packet_rtt_.size())
407 return false; 409 return false;
408 packets_received_mask_.set(packet_index); 410 packets_received_mask_.set(packet_index);
409 TestType test_type = test_sequence_[current_test_index_]; 411 TestType test_type = test_sequence_[current_test_index_];
410 uint32 received_packets = packets_received_mask_.count(); 412 uint32 received_packets = packets_received_mask_.count();
411 413
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 } 525 }
524 if (received_packets >= kMinimumReceivedPacketsForNATTest) { 526 if (received_packets >= kMinimumReceivedPacketsForNATTest) {
525 test_sequence_.push_back(TOKEN_REQUEST); 527 test_sequence_.push_back(TOKEN_REQUEST);
526 test_sequence_.push_back(NAT_BIND_TEST); 528 test_sequence_.push_back(NAT_BIND_TEST);
527 test_sequence_.push_back(TOKEN_REQUEST); 529 test_sequence_.push_back(TOKEN_REQUEST);
528 } 530 }
529 } 531 }
530 TestPhaseComplete(READ_TIMED_OUT, net::ERR_FAILED); 532 TestPhaseComplete(READ_TIMED_OUT, net::ERR_FAILED);
531 } 533 }
532 534
533 void NetworkStats::TestPhaseComplete(Status status, int result) { 535 bool NetworkStats::TestPhaseComplete(Status status, int result) {
534 // If there is no valid token, do nothing and delete self. 536 // If there is no valid token, do nothing and delete self.
535 // This includes all connection error, name resolve error, etc. 537 // This includes all connection error, name resolve error, etc.
536 if (write_state_ == WRITE_STATE_WRITE_PENDING) { 538 if (write_state_ == WRITE_STATE_WRITE_PENDING) {
537 UMA_HISTOGRAM_BOOLEAN("NetConnectivity5.TestFailed.WritePending", true); 539 UMA_HISTOGRAM_BOOLEAN("NetConnectivity5.TestFailed.WritePending", true);
538 } else if (token_.timestamp_micros() != 0 && 540 } else if (status == SUCCESS || status == READ_TIMED_OUT) {
539 (status == SUCCESS || status == READ_TIMED_OUT)) {
540 TestType current_test = test_sequence_[current_test_index_]; 541 TestType current_test = test_sequence_[current_test_index_];
541 DCHECK_LT(current_test, TEST_TYPE_MAX); 542 DCHECK_LT(current_test, TEST_TYPE_MAX);
542 if (current_test != TOKEN_REQUEST) { 543 if (current_test != TOKEN_REQUEST) {
543 RecordHistograms(current_test); 544 RecordHistograms(current_test);
544 } else if (current_test_index_ > 0) { 545 } else if (current_test_index_ > 0) {
545 if (test_sequence_[current_test_index_ - 1] == NAT_BIND_TEST) { 546 if (test_sequence_[current_test_index_ - 1] == NAT_BIND_TEST) {
546 // We record the NATTestReceivedHistograms after the succeeding 547 // We record the NATTestReceivedHistograms after the succeeding
547 // TokenRequest. 548 // TokenRequest.
548 RecordNATTestReceivedHistograms(status); 549 RecordNATTestReceivedHistograms(status);
549 } else if (test_sequence_[current_test_index_ - 1] == PACKET_SIZE_TEST) { 550 } else if (test_sequence_[current_test_index_ - 1] == PACKET_SIZE_TEST) {
550 // We record the PacketSizeTestReceivedHistograms after the succeeding 551 // We record the PacketSizeTestReceivedHistograms after the succeeding
551 // TokenRequest. 552 // TokenRequest.
552 RecordPacketSizeTestReceivedHistograms(status); 553 RecordPacketSizeTestReceivedHistograms(status);
553 } 554 }
554 } 555 }
555 556
556 // Move to the next test. 557 // Move to the next test.
557 current_test = GetNextTest(); 558 current_test = GetNextTest();
558 if (current_test_index_ <= maximum_tests_ && current_test < TEST_TYPE_MAX) { 559 if (current_test_index_ <= maximum_tests_ && current_test < TEST_TYPE_MAX) {
559 DVLOG(1) << "NetworkStat: Start Probe test: " << current_test; 560 DVLOG(1) << "NetworkStat: Start Probe test: " << current_test;
560 base::MessageLoop::current()->PostTask( 561 base::MessageLoop::current()->PostTask(
561 FROM_HERE, 562 FROM_HERE,
562 base::Bind(&NetworkStats::StartOneTest, weak_factory_.GetWeakPtr())); 563 base::Bind(&NetworkStats::StartOneTest, weak_factory_.GetWeakPtr()));
563 return; 564 return false;
564 } 565 }
565 } 566 }
566 567
567 // All tests are done. 568 // All tests are done.
568 DoFinishCallback(result); 569 DoFinishCallback(result);
569 570
570 // Close the socket so that there are no more IO operations. 571 // Close the socket so that there are no more IO operations.
571 if (socket_.get()) 572 if (socket_.get())
572 socket_->Close(); 573 socket_->Close();
573 574
574 DVLOG(1) << "NetworkStat: schedule delete self at test index " 575 DVLOG(1) << "NetworkStat: schedule delete self at test index "
575 << current_test_index_; 576 << current_test_index_;
576 delete this; 577 delete this;
578 return true;
577 } 579 }
578 580
579 NetworkStats::TestType NetworkStats::GetNextTest() { 581 NetworkStats::TestType NetworkStats::GetNextTest() {
580 ++current_test_index_; 582 ++current_test_index_;
581 if (current_test_index_ >= test_sequence_.size()) 583 if (current_test_index_ >= test_sequence_.size())
582 return TEST_TYPE_MAX; 584 return TEST_TYPE_MAX;
583 return test_sequence_[current_test_index_]; 585 return test_sequence_[current_test_index_];
584 } 586 }
585 587
586 void NetworkStats::DoFinishCallback(int result) { 588 void NetworkStats::DoFinishCallback(int result) {
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 udp_stats_client->Start(host_resolver, 947 udp_stats_client->Start(host_resolver,
946 server_address, 948 server_address,
947 histogram_port, 949 histogram_port,
948 has_proxy_server, 950 has_proxy_server,
949 kProbePacketBytes[probe_choice], 951 kProbePacketBytes[probe_choice],
950 bytes_for_packet_size_test, 952 bytes_for_packet_size_test,
951 net::CompletionCallback()); 953 net::CompletionCallback());
952 } 954 }
953 955
954 } // namespace chrome_browser_net 956 } // namespace chrome_browser_net
OLDNEW
« no previous file with comments | « chrome/browser/net/network_stats.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698