From cceb166a3fd2724c679da7d093149b0511e8d99b Mon Sep 17 00:00:00 2001 From: "jiayl@webrtc.org" Date: Thu, 22 Jan 2015 00:55:10 +0000 Subject: [PATCH] Fix a use-after-free when sending queued messages is aborted for blocked channel. BUG=4187 R=pthatcher@webrtc.org Review URL: https://webrtc-codereview.appspot.com/39519004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@8119 4adac7df-926f-26a2-2b94-8c16560cd09d --- talk/app/webrtc/datachannel.cc | 4 +++- talk/app/webrtc/datachannel_unittest.cc | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/talk/app/webrtc/datachannel.cc b/talk/app/webrtc/datachannel.cc index f9765aac7c..05c934cd8a 100644 --- a/talk/app/webrtc/datachannel.cc +++ b/talk/app/webrtc/datachannel.cc @@ -463,11 +463,13 @@ void DataChannel::SendQueuedDataMessages() { ASSERT(was_ever_writable_ && state_ == kOpen); while (!queued_send_data_.Empty()) { - rtc::scoped_ptr buffer(queued_send_data_.Front()); + DataBuffer* buffer = queued_send_data_.Front(); if (!SendDataMessage(*buffer, false)) { + // Leave the message in the queue if sending is aborted. break; } queued_send_data_.Pop(); + delete buffer; } } diff --git a/talk/app/webrtc/datachannel_unittest.cc b/talk/app/webrtc/datachannel_unittest.cc index 30bb576e98..6a73fbc3a6 100644 --- a/talk/app/webrtc/datachannel_unittest.cc +++ b/talk/app/webrtc/datachannel_unittest.cc @@ -162,6 +162,24 @@ TEST_F(SctpDataChannelTest, QueuedDataSentWhenUnblocked) { EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount()); } +// Tests that no crash when the channel is blocked right away while trying to +// send queued data. +TEST_F(SctpDataChannelTest, BlockedWhenSendQueuedDataNoCrash) { + SetChannelReady(); + webrtc::DataBuffer buffer("abcd"); + provider_.set_send_blocked(true); + EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); + + // Set channel ready while it is still blocked. + SetChannelReady(); + EXPECT_EQ(buffer.size(), webrtc_data_channel_->buffered_amount()); + + // Unblock the channel to send queued data again, there should be no crash. + provider_.set_send_blocked(false); + SetChannelReady(); + EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount()); +} + // Tests that the queued control message is sent when channel is ready. TEST_F(SctpDataChannelTest, OpenMessageSent) { // Initially the id is unassigned.