From 92a773ddb6d311f4898f4bfcfeb1a3aaa1e0b195 Mon Sep 17 00:00:00 2001 From: Elad Alon Date: Fri, 13 Oct 2017 11:54:51 +0200 Subject: [PATCH] Prevent unbounded memory consumption through RtcEventLogImpl::config_history_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The config-history is (logically) intended to be unlimited, but in practice, it would be good to cap it, even though the cap is never expected to be reached, so as to prevent a possible attack that would cause memory overuse. Bug: webrtc:8111 Change-Id: I1f60cf10215bf8191a8ab3c9b19345104c585483 Reviewed-on: https://webrtc-review.googlesource.com/8980 Commit-Queue: Elad Alon Reviewed-by: Björn Terelius Cr-Commit-Position: refs/heads/master@{#20276} --- logging/rtc_event_log/rtc_event_log.cc | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/logging/rtc_event_log/rtc_event_log.cc b/logging/rtc_event_log/rtc_event_log.cc index 22dd2871c2..7d9115f276 100644 --- a/logging/rtc_event_log/rtc_event_log.cc +++ b/logging/rtc_event_log/rtc_event_log.cc @@ -37,7 +37,10 @@ namespace webrtc { #ifdef ENABLE_RTC_EVENT_LOG namespace { -const int kEventsInHistory = 10000; +constexpr size_t kMaxEventsInHistory = 10000; +// The config-history is supposed to be unbounded, but needs to have some bound +// to prevent an attack via unreasonable memory use. +constexpr size_t kMaxEventsInConfigHistory = 1000; // Observe a limit on the number of concurrent logs, so as not to run into // OS-imposed limits on open files and/or threads/task-queues. @@ -114,7 +117,7 @@ class RtcEventLogImpl final : public RtcEventLog { rtc::SequencedTaskChecker owner_sequence_checker_; // History containing all past configuration events. - std::vector> config_history_ + std::deque> config_history_ RTC_ACCESS_ON(task_queue_); // History containing the most recent (non-configuration) events (~10s). @@ -237,14 +240,15 @@ bool RtcEventLogImpl::AppendEventToString(const RtcEvent& event, void RtcEventLogImpl::LogToMemory(std::unique_ptr event) { RTC_DCHECK(!event_output_); - if (event->IsConfigEvent()) { - config_history_.push_back(std::move(event)); - } else { - history_.push_back(std::move(event)); - if (history_.size() > kEventsInHistory) { - history_.pop_front(); - } + std::deque>& container = + event->IsConfigEvent() ? config_history_ : history_; + const size_t container_max_size = + event->IsConfigEvent() ? kMaxEventsInHistory : kMaxEventsInConfigHistory; + + if (container.size() >= container_max_size) { + container.pop_front(); } + container.push_back(std::move(event)); } void RtcEventLogImpl::LogEventsFromMemoryToOutput() {