summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Nguyen <tungnh@google.com>2022-11-21 11:42:19 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2023-01-16 21:25:10 +0000
commitee6f7906f9b7194b0bbf50596e38013e26682765 (patch)
tree09924170012c06bed687333ea94cc9e90e347199
parent1f19a05eaa8835a904108a3803aec11f78f6e826 (diff)
downloadqtwebengine-chromium-ee6f7906f9b7194b0bbf50596e38013e26682765.tar.gz
[Backport] CVE-2023-0132: Inappropriate implementation in Permission prompts
Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/4030554: Bind dialog input protector to it's anchor widget changed event. Bug: 1371215 (cherry picked from commit 0040cb967d7469250444603bdf1aa6e4d2ae822e) Change-Id: I39b9ea632447e1e7d4ba1b1d57f67a293c751b62 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4016874 Reviewed-by: Allen Bauer <kylixrd@chromium.org> Commit-Queue: Thomas Nguyen <tungnh@google.com> Cr-Original-Commit-Position: refs/heads/main@{#1070921} Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4030554 Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Auto-Submit: Thomas Nguyen <tungnh@google.com> Cr-Commit-Position: refs/branch-heads/5414@{#158} Cr-Branched-From: 4417ee59d7bf6df7a9c9ea28f7722d2ee6203413-refs/heads/main@{#1070088} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/454211 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--chromium/ui/views/bubble/bubble_dialog_delegate_view.cc11
-rw-r--r--chromium/ui/views/bubble/bubble_dialog_delegate_view.h4
-rw-r--r--chromium/ui/views/bubble/bubble_frame_view.cc4
-rw-r--r--chromium/ui/views/bubble/bubble_frame_view.h6
-rw-r--r--chromium/ui/views/input_event_activation_protector.cc8
-rw-r--r--chromium/ui/views/input_event_activation_protector.h5
-rw-r--r--chromium/ui/views/window/dialog_client_view.cc4
-rw-r--r--chromium/ui/views/window/dialog_client_view.h4
-rw-r--r--chromium/ui/views/window/dialog_delegate.cc8
-rw-r--r--chromium/ui/views/window/dialog_delegate.h12
10 files changed, 55 insertions, 11 deletions
diff --git a/chromium/ui/views/bubble/bubble_dialog_delegate_view.cc b/chromium/ui/views/bubble/bubble_dialog_delegate_view.cc
index 2a84e8f5a70..e6fdc8f2583 100644
--- a/chromium/ui/views/bubble/bubble_dialog_delegate_view.cc
+++ b/chromium/ui/views/bubble/bubble_dialog_delegate_view.cc
@@ -43,6 +43,7 @@
#include "ui/views/views_features.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
+#include "ui/views/window/dialog_client_view.h"
#if BUILDFLAG(IS_WIN)
#include "ui/base/win/shell.h"
@@ -797,6 +798,16 @@ void BubbleDialogDelegate::OnAnchorBoundsChanged() {
// TODO(pbos): Reconsider whether to update the anchor when the view isn't
// drawn.
SizeToContents();
+
+ // We will not accept input event a short time after anchored view changed.
+ UpdateInputProtectorsTimeStamp();
+}
+
+void BubbleDialogDelegate::UpdateInputProtectorsTimeStamp() {
+ if (auto* dialog = GetDialogClientView())
+ dialog->UpdateInputProtectorTimeStamp();
+
+ GetBubbleFrameView()->UpdateInputProtectorTimeStamp();
}
gfx::Rect BubbleDialogDelegate::GetBubbleBounds() {
diff --git a/chromium/ui/views/bubble/bubble_dialog_delegate_view.h b/chromium/ui/views/bubble/bubble_dialog_delegate_view.h
index 27f16a49a39..38b629ce133 100644
--- a/chromium/ui/views/bubble/bubble_dialog_delegate_view.h
+++ b/chromium/ui/views/bubble/bubble_dialog_delegate_view.h
@@ -144,6 +144,10 @@ class VIEWS_EXPORT BubbleDialogDelegate : public DialogDelegate {
// normally, do not call this.
void OnAnchorBoundsChanged();
+ // Call this method to update view shown time stamp of underneath input
+ // protectors.
+ void UpdateInputProtectorsTimeStamp();
+
//////////////////////////////////////////////////////////////////////////////
// Subtitle:
//
diff --git a/chromium/ui/views/bubble/bubble_frame_view.cc b/chromium/ui/views/bubble/bubble_frame_view.cc
index b0fe19b0bd3..c39b8e9e5ed 100644
--- a/chromium/ui/views/bubble/bubble_frame_view.cc
+++ b/chromium/ui/views/bubble/bubble_frame_view.cc
@@ -768,6 +768,10 @@ gfx::Rect BubbleFrameView::GetUpdatedWindowBounds(
return bubble_border_->GetBounds(anchor_rect, size);
}
+void BubbleFrameView::UpdateInputProtectorTimeStamp() {
+ input_protector_.UpdateViewShownTimeStamp();
+}
+
void BubbleFrameView::ResetViewShownTimeStampForTesting() {
input_protector_.ResetForTesting();
}
diff --git a/chromium/ui/views/bubble/bubble_frame_view.h b/chromium/ui/views/bubble/bubble_frame_view.h
index fe1f9f9b2b4..def45c594c6 100644
--- a/chromium/ui/views/bubble/bubble_frame_view.h
+++ b/chromium/ui/views/bubble/bubble_frame_view.h
@@ -174,6 +174,10 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView {
View* GetHeaderViewForTesting() const { return header_view_; }
+ // Update the |view_shown_time_stamp_| of input protector. A short time
+ // from this point onward, input event will be ignored.
+ void UpdateInputProtectorTimeStamp();
+
// Resets the time when view has been shown. Tests may need to call this
// method if they use events that could be otherwise treated as unintended.
// See IsPossiblyUnintendedInteraction().
@@ -210,6 +214,8 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView {
IgnorePossiblyUnintendedClicksClose);
FRIEND_TEST_ALL_PREFIXES(BubbleFrameViewTest,
IgnorePossiblyUnintendedClicksMinimize);
+ FRIEND_TEST_ALL_PREFIXES(BubbleFrameViewTest,
+ IgnorePossiblyUnintendedClicksAnchorBoundsChanged);
FRIEND_TEST_ALL_PREFIXES(BubbleDelegateTest, CloseReasons);
FRIEND_TEST_ALL_PREFIXES(BubbleDialogDelegateViewTest, CloseMethods);
FRIEND_TEST_ALL_PREFIXES(BubbleDialogDelegateViewTest, CreateDelegate);
diff --git a/chromium/ui/views/input_event_activation_protector.cc b/chromium/ui/views/input_event_activation_protector.cc
index 9938421cf3f..387e13b6370 100644
--- a/chromium/ui/views/input_event_activation_protector.cc
+++ b/chromium/ui/views/input_event_activation_protector.cc
@@ -18,6 +18,14 @@ void InputEventActivationProtector::VisibilityChanged(bool is_visible) {
view_shown_time_stamp_ = base::TimeTicks::Now();
}
+void InputEventActivationProtector::UpdateViewShownTimeStamp() {
+ // The UI was never shown, ignore.
+ if (view_shown_time_stamp_ == base::TimeTicks())
+ return;
+
+ view_shown_time_stamp_ = base::TimeTicks::Now();
+}
+
bool InputEventActivationProtector::IsPossiblyUnintendedInteraction(
const ui::Event& event) {
if (g_disable_for_testing)
diff --git a/chromium/ui/views/input_event_activation_protector.h b/chromium/ui/views/input_event_activation_protector.h
index d5828b36083..a980ca83182 100644
--- a/chromium/ui/views/input_event_activation_protector.h
+++ b/chromium/ui/views/input_event_activation_protector.h
@@ -30,6 +30,11 @@ class VIEWS_EXPORT InputEventActivationProtector {
// method must be called when the visibility of the view is changed.
void VisibilityChanged(bool is_visible);
+ // Updates the |view_shown_time_stamp_| if needed. This function will be
+ // called when we want to reset back the input protector to "initial shown"
+ // state, basically under some certain view's proprieties changed events.
+ void UpdateViewShownTimeStamp();
+
// Returns true if the event is a mouse, touch, or pointer event that took
// place within the double-click time interval after |view_shown_time_stamp_|.
bool IsPossiblyUnintendedInteraction(const ui::Event& event);
diff --git a/chromium/ui/views/window/dialog_client_view.cc b/chromium/ui/views/window/dialog_client_view.cc
index 3095f350643..cd33d929533 100644
--- a/chromium/ui/views/window/dialog_client_view.cc
+++ b/chromium/ui/views/window/dialog_client_view.cc
@@ -225,6 +225,10 @@ void DialogClientView::OnThemeChanged() {
}
}
+void DialogClientView::UpdateInputProtectorTimeStamp() {
+ input_protector_.UpdateViewShownTimeStamp();
+}
+
void DialogClientView::ResetViewShownTimeStampForTesting() {
input_protector_.ResetForTesting();
}
diff --git a/chromium/ui/views/window/dialog_client_view.h b/chromium/ui/views/window/dialog_client_view.h
index 1255a3cc74c..1d298953b24 100644
--- a/chromium/ui/views/window/dialog_client_view.h
+++ b/chromium/ui/views/window/dialog_client_view.h
@@ -63,6 +63,10 @@ class VIEWS_EXPORT DialogClientView : public ClientView, public DialogObserver {
const ViewHierarchyChangedDetails& details) override;
void OnThemeChanged() override;
+ // Update the |view_shown_time_stamp_| of input protector. A short time
+ // from this point onward, input event will be ignored.
+ void UpdateInputProtectorTimeStamp();
+
void set_minimum_size(const gfx::Size& size) { minimum_size_ = size; }
// Resets the time when view has been shown. Tests may need to call this
diff --git a/chromium/ui/views/window/dialog_delegate.cc b/chromium/ui/views/window/dialog_delegate.cc
index bc0a51138f2..54cd17c8598 100644
--- a/chromium/ui/views/window/dialog_delegate.cc
+++ b/chromium/ui/views/window/dialog_delegate.cc
@@ -275,12 +275,8 @@ const DialogClientView* DialogDelegate::GetDialogClientView() const {
}
DialogClientView* DialogDelegate::GetDialogClientView() {
- if (!GetWidget())
- return nullptr;
- views::View* client_view = GetWidget()->client_view();
- return client_view->GetClassName() == DialogClientView::kViewClassName
- ? static_cast<DialogClientView*>(client_view)
- : nullptr;
+ return const_cast<DialogClientView*>(
+ const_cast<const DialogDelegate*>(this)->GetDialogClientView());
}
BubbleFrameView* DialogDelegate::GetBubbleFrameView() const {
diff --git a/chromium/ui/views/window/dialog_delegate.h b/chromium/ui/views/window/dialog_delegate.h
index 84430f84e9b..09f95e99a53 100644
--- a/chromium/ui/views/window/dialog_delegate.h
+++ b/chromium/ui/views/window/dialog_delegate.h
@@ -178,6 +178,13 @@ class VIEWS_EXPORT DialogDelegate : public WidgetDelegate {
// will only be created when use_custom_frame() is true.
BubbleFrameView* GetBubbleFrameView() const;
+ // A helper for accessing the DialogClientView object contained by this
+ // delegate's Window. This function can return nullptr if the |client_view| is
+ // a DialogClientView subclass which also has metadata or overrides
+ // GetClassName().
+ const DialogClientView* GetDialogClientView() const;
+ DialogClientView* GetDialogClientView();
+
// Helpers for accessing parts of the DialogClientView without needing to know
// about DialogClientView. Do not call these before OnWidgetInitialized().
views::LabelButton* GetOkButton() const;
@@ -316,11 +323,6 @@ class VIEWS_EXPORT DialogDelegate : public WidgetDelegate {
std::unique_ptr<View> DisownFootnoteView();
private:
- // A helper for accessing the DialogClientView object contained by this
- // delegate's Window.
- const DialogClientView* GetDialogClientView() const;
- DialogClientView* GetDialogClientView();
-
// Runs a close callback, ensuring that at most one close callback is ever
// run.
void RunCloseCallback(base::OnceClosure callback);