diff options
author | Thomas Nguyen <tungnh@google.com> | 2022-11-21 11:42:19 +0000 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2023-01-16 21:25:10 +0000 |
commit | ee6f7906f9b7194b0bbf50596e38013e26682765 (patch) | |
tree | 09924170012c06bed687333ea94cc9e90e347199 | |
parent | 1f19a05eaa8835a904108a3803aec11f78f6e826 (diff) | |
download | qtwebengine-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.cc | 11 | ||||
-rw-r--r-- | chromium/ui/views/bubble/bubble_dialog_delegate_view.h | 4 | ||||
-rw-r--r-- | chromium/ui/views/bubble/bubble_frame_view.cc | 4 | ||||
-rw-r--r-- | chromium/ui/views/bubble/bubble_frame_view.h | 6 | ||||
-rw-r--r-- | chromium/ui/views/input_event_activation_protector.cc | 8 | ||||
-rw-r--r-- | chromium/ui/views/input_event_activation_protector.h | 5 | ||||
-rw-r--r-- | chromium/ui/views/window/dialog_client_view.cc | 4 | ||||
-rw-r--r-- | chromium/ui/views/window/dialog_client_view.h | 4 | ||||
-rw-r--r-- | chromium/ui/views/window/dialog_delegate.cc | 8 | ||||
-rw-r--r-- | chromium/ui/views/window/dialog_delegate.h | 12 |
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); |