-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FLEDGE] Only allow 20 active cross-origin IG joins and leaves per frame
This is largely to prevent buggy pages from OOM-ing the browser process, or from causing a ton of background requests long after a tab has been closed. This does not provide protection against compromised renderers or malicious actors with lots of iframes from causing these issues, but as neither is a security issue, best effort protection seems good enough here, unless it becomes a problem. Bug: 1315805 Change-Id: I43e1cae49d2b0a616d3c97e929fdb5c693028b0e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3614951 Reviewed-by: Qingxin Wu <qingxinwu@google.com> Reviewed-by: Maks Orlovich <morlovich@chromium.org> Commit-Queue: Matt Menke <mmenke@chromium.org> Cr-Commit-Position: refs/heads/main@{#1001567}
- Loading branch information
Matt Menke
authored and
Chromium LUCI CQ
committed
May 10, 2022
1 parent
723deb1
commit 6ee98da
Showing
9 changed files
with
741 additions
and
13 deletions.
There are no files selected for viewing
450 changes: 450 additions & 0 deletions
450
content/browser/interest_group/interest_group_browsertest.cc
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
third_party/blink/renderer/modules/ad_auction/join_leave_queue.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_AD_AUCTION_JOIN_LEAVE_QUEUE_H_ | ||
#define THIRD_PARTY_BLINK_RENDERER_MODULES_AD_AUCTION_JOIN_LEAVE_QUEUE_H_ | ||
|
||
#include "base/callback.h" | ||
#include "base/check.h" | ||
#include "third_party/blink/renderer/platform/wtf/deque.h" | ||
|
||
namespace blink { | ||
|
||
// A FIFO queue for interest group joins and leaves. It ensures there are never | ||
// more than `max_active` started requests, adding requests to a queue if they | ||
// can't be immediately started. Once the consumer informs it when a previously | ||
// start request completes, it will start another request, if one is queued. | ||
// | ||
// This is a separate class so it can be unit tested. | ||
template <typename T> | ||
class JoinLeaveQueue { | ||
public: | ||
using StartCallback = base::RepeatingCallback<void(T&& operation)>; | ||
|
||
// `max_active` is the maximum number of active operations at a time. `start` | ||
// is invoked to start an operation. `this` may not called into or deleted | ||
// while `start` is being invoked. | ||
JoinLeaveQueue(int max_active, StartCallback start) | ||
: max_active_(max_active), start_(start) {} | ||
|
||
JoinLeaveQueue(JoinLeaveQueue&) = delete; | ||
JoinLeaveQueue& operator=(JoinLeaveQueue&) = delete; | ||
|
||
~JoinLeaveQueue() = default; | ||
|
||
// If there are fewer than `max_active` operations, immediately invokes | ||
// `start` with operation. Otherwise enqueues `operation`. | ||
void Enqueue(T&& operation) { | ||
if (num_active_ < max_active_) { | ||
++num_active_; | ||
start_.Run(std::move(operation)); | ||
return; | ||
} | ||
|
||
queue_.push_back(std::move(operation)); | ||
} | ||
|
||
// Called when a previously started operation completes. Starts the next | ||
// queued operation, if there is one. | ||
void OnComplete() { | ||
DCHECK_GT(num_active_, 0); | ||
|
||
if (!queue_.empty()) { | ||
DCHECK_EQ(num_active_, max_active_); | ||
start_.Run(queue_.TakeFirst()); | ||
return; | ||
} | ||
|
||
--num_active_; | ||
} | ||
|
||
int num_active_for_testing() const { return num_active_; } | ||
|
||
private: | ||
// Maximum number of active operations. | ||
const int max_active_; | ||
|
||
// Callback to start the input operation. | ||
const StartCallback start_; | ||
|
||
// Current number of active operations. Active operations are not included in | ||
// `queue_`. | ||
int num_active_ = 0; | ||
|
||
// FIFO queue of operations that have not yet started. | ||
Deque<T> queue_; | ||
}; | ||
|
||
} // namespace blink | ||
|
||
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_AD_AUCTION_JOIN_LEAVE_QUEUE_H_ |
92 changes: 92 additions & 0 deletions
92
third_party/blink/renderer/modules/ad_auction/join_leave_queue_test.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// Copyright 2021 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "third_party/blink/renderer/modules/ad_auction/join_leave_queue.h" | ||
|
||
#include <memory> | ||
#include <vector> | ||
|
||
#include "base/bind.h" | ||
#include "testing/gmock/include/gmock/gmock.h" | ||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
namespace blink { | ||
|
||
class JoinLeaveQueueTest : public testing::Test { | ||
public: | ||
JoinLeaveQueueTest() | ||
: queue_(std::make_unique<JoinLeaveQueue<int>>( | ||
/*max_active=*/2, | ||
base::BindRepeating(&JoinLeaveQueueTest::Start, | ||
base::Unretained(this)))) {} | ||
|
||
protected: | ||
void Start(int&& i) { start_order_.push_back(i); } | ||
|
||
std::unique_ptr<JoinLeaveQueue<int>> queue_; | ||
|
||
std::vector<int> start_order_; | ||
}; | ||
|
||
TEST_F(JoinLeaveQueueTest, Basic) { | ||
EXPECT_EQ(0, queue_->num_active_for_testing()); | ||
|
||
queue_->Enqueue(0); | ||
EXPECT_THAT(start_order_, testing::ElementsAre(0)); | ||
EXPECT_EQ(1, queue_->num_active_for_testing()); | ||
|
||
queue_->Enqueue(1); | ||
EXPECT_THAT(start_order_, testing::ElementsAre(0, 1)); | ||
EXPECT_EQ(2, queue_->num_active_for_testing()); | ||
|
||
queue_->OnComplete(); | ||
queue_->OnComplete(); | ||
EXPECT_THAT(start_order_, testing::ElementsAre(0, 1)); | ||
EXPECT_EQ(0, queue_->num_active_for_testing()); | ||
} | ||
|
||
TEST_F(JoinLeaveQueueTest, ExceedsLimit) { | ||
queue_->Enqueue(0); | ||
queue_->Enqueue(1); | ||
queue_->Enqueue(2); | ||
queue_->Enqueue(3); | ||
queue_->Enqueue(4); | ||
EXPECT_THAT(start_order_, testing::ElementsAre(0, 1)); | ||
EXPECT_EQ(2, queue_->num_active_for_testing()); | ||
|
||
queue_->OnComplete(); | ||
EXPECT_THAT(start_order_, testing::ElementsAre(0, 1, 2)); | ||
EXPECT_EQ(2, queue_->num_active_for_testing()); | ||
|
||
queue_->OnComplete(); | ||
EXPECT_THAT(start_order_, testing::ElementsAre(0, 1, 2, 3)); | ||
EXPECT_EQ(2, queue_->num_active_for_testing()); | ||
|
||
queue_->OnComplete(); | ||
EXPECT_THAT(start_order_, testing::ElementsAre(0, 1, 2, 3, 4)); | ||
EXPECT_EQ(2, queue_->num_active_for_testing()); | ||
|
||
queue_->OnComplete(); | ||
EXPECT_THAT(start_order_, testing::ElementsAre(0, 1, 2, 3, 4)); | ||
EXPECT_EQ(1, queue_->num_active_for_testing()); | ||
|
||
queue_->OnComplete(); | ||
EXPECT_THAT(start_order_, testing::ElementsAre(0, 1, 2, 3, 4)); | ||
EXPECT_EQ(0, queue_->num_active_for_testing()); | ||
} | ||
|
||
TEST_F(JoinLeaveQueueTest, DestroyedWithRequestsQueued) { | ||
queue_->Enqueue(0); | ||
queue_->Enqueue(1); | ||
queue_->Enqueue(2); | ||
queue_->Enqueue(3); | ||
|
||
EXPECT_THAT(start_order_, testing::ElementsAre(0, 1)); | ||
EXPECT_EQ(2, queue_->num_active_for_testing()); | ||
|
||
queue_.reset(); | ||
EXPECT_THAT(start_order_, testing::ElementsAre(0, 1)); | ||
} | ||
|
||
} // namespace blink |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.