Prevent unbounded memory consumption through RtcEventLogImpl::config_history_

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 <eladalon@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20276}
This commit is contained in:
Elad Alon 2017-10-13 11:54:51 +02:00 committed by Commit Bot
parent f0878c98dc
commit 92a773ddb6

View File

@ -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<std::unique_ptr<RtcEvent>> config_history_
std::deque<std::unique_ptr<RtcEvent>> 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<RtcEvent> 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<std::unique_ptr<RtcEvent>>& 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() {