Fix CVE-2020-26979

This commit is contained in:
lvfei 2024-06-05 20:19:34 +08:00
parent 282dd3cec0
commit 9d065fe77c
2 changed files with 317 additions and 1 deletions

311
CVE-2020-26979.patch Normal file
View File

@ -0,0 +1,311 @@
From 36d469443d498a2b24079776b6e24afbd9fa7248 Mon Sep 17 00:00:00 2001
From: Daisuke Akatsuka <daisuke@birchill.co.jp>
Date: Mon, 26 Oct 2020 05:30:44 +0000 (2020-10-26)
Subject: [PATCH] CVE-2020-26979
---
browser/base/content/utilityOverlay.js | 7 +-
browser/components/urlbar/UrlbarInput.jsm | 63 +++++++++--
.../urlbar/tests/browser/browser_enter.js | 100 ++++++++++++++++--
3 files changed, 147 insertions(+), 23 deletions(-)
diff --git a/browser/base/content/utilityOverlay.js b/browser/base/content/utilityOverlay.js
index a23d6f05e6..c9d0ef8a71 100644
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -695,8 +695,11 @@ function openLinkIn(url, where, params) {
}
break;
}
-
- if (!focusUrlBar && targetBrowser == w.gBrowser.selectedBrowser) {
+ if (
+ !params.avoidBrowserFocus &&
+ !focusUrlBar &&
+ targetBrowser == w.gBrowser.selectedBrowser
+ ) {
// Focus the content, but only if the browser used for the load is selected.
targetBrowser.focus();
}
diff --git a/browser/components/urlbar/UrlbarInput.jsm b/browser/components/urlbar/UrlbarInput.jsm
index 366149ec07..b9a916ca1b 100644
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -16,6 +16,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
ExtensionSearchHandler: "resource://gre/modules/ExtensionSearchHandler.jsm",
FormHistory: "resource://gre/modules/FormHistory.jsm",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
+ PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
ReaderMode: "resource://gre/modules/ReaderMode.jsm",
Services: "resource://gre/modules/Services.jsm",
TopSiteAttribution: "resource:///modules/TopSiteAttribution.jsm",
@@ -474,7 +475,7 @@ class UrlbarInput {
isValidUrl = true;
} catch (ex) {}
if (isValidUrl) {
- this._loadURL(url, where, openParams);
+ this._loadURL(url, event, where, openParams);
return;
}
@@ -528,8 +529,8 @@ class UrlbarInput {
browser.lastLocationChange == lastLocationChange
) {
openParams.postData = postData.value;
- this._loadURL(uri.spec, where, openParams, null, browser);
- }
+ this._loadURL(uri.spec, event, where, openParams, null, browser);
+ }
}
});
// Don't add further handling here, the catch above is our last resort.
@@ -600,8 +601,8 @@ class UrlbarInput {
selIndex,
selType: "canonized",
});
- this._loadURL(this.value, where, openParams, browser);
- return;
+ this._loadURL(this.value, event, where, openParams, browser);
+ return;
}
let { url, postData } = UrlbarUtils.getUrlFromResult(result);
@@ -844,6 +845,7 @@ class UrlbarInput {
this._loadURL(
url,
+ event,
where,
openParams,
{
@@ -1757,6 +1759,8 @@ class UrlbarInput {
*
* @param {string} url
* The URL to open.
+ @param {Event} event
+ * The event that triggered to load the url.
* @param {string} openUILinkWhere
* Where we expect the result to be opened.
* @param {object} params
@@ -1778,6 +1782,7 @@ class UrlbarInput {
*/
_loadURL(
url,
+ event,
openUILinkWhere,
params,
resultDetails = null,
@@ -1835,12 +1840,19 @@ class UrlbarInput {
} else {
params.initiatingDoc = this.window.document;
}
+ if (event?.keyCode === KeyEvent.DOM_VK_RETURN) {
+ if (openUILinkWhere === "current") {
+ params.avoidBrowserFocus = true;
+ this._keyDownEnterDeferred?.resolve(browser);
+ }
+ }
// Focus the content area before triggering loads, since if the load
// occurs in a new tab, we want focus to be restored to the content
// area when the current tab is re-selected.
- browser.focus();
-
+ if (!params.avoidBrowserFocus) {
+ browser.focus();
+ }
if (openUILinkWhere != "current") {
this.handleRevert();
}
@@ -2059,7 +2071,14 @@ class UrlbarInput {
) {
this.window.UpdatePopupNotificationsVisibility();
}
-
+
+ // If user move the focus to another component while pressing Enter key,
+ // then keyup at that component, as we can't get the event, clear the promise.
+ if (this._keyDownEnterDeferred) {
+ this._keyDownEnterDeferred.resolve();
+ this._keyDownEnterDeferred = null;
+ }
+
Services.obs.notifyObservers(null, "urlbar-blur");
}
@@ -2376,6 +2395,12 @@ class UrlbarInput {
}
_on_keydown(event) {
+ if (event.keyCode === KeyEvent.DOM_VK_RETURN) {
+ if (this._keyDownEnterDeferred) {
+ this._keyDownEnterDeferred.reject();
+ }
+ this._keyDownEnterDeferred = PromiseUtils.defer();
+ }
// Due to event deferring, it's possible preventDefault() won't be invoked
// soon enough to actually prevent some of the default behaviors, thus we
// have to handle the event "twice". This first immediate call passes false
@@ -2391,9 +2416,27 @@ class UrlbarInput {
this.controller.handleKeyNavigation(event);
});
}
+
+ async _on_keyup(event) {
+ if (
+ event.keyCode === KeyEvent.DOM_VK_RETURN &&
+ this._keyDownEnterDeferred
+ ) {
+ try {
+ const loadingBrowser = await this._keyDownEnterDeferred.promise;
+ // Ensure the selected browser didn't change in the meanwhile.
+ if (this.window.gBrowser.selectedBrowser === loadingBrowser) {
+ loadingBrowser.focus();
+ }
+ } catch (ex) {
+ // Not all the Enter actions in the urlbar will cause a navigation, then it
+ // is normal for this to be rejected.
+ }
+ this._keyDownEnterDeferred = null;
+ return;
+ }
- _on_keyup(event) {
- this._toggleActionOverride(event);
+ this._toggleActionOverride(event);
}
_on_compositionstart(event) {
diff --git a/browser/components/urlbar/tests/browser/browser_enter.js b/browser/components/urlbar/tests/browser/browser_enter.js
index 3eb6df89c7..6d89815345 100644
--- a/browser/components/urlbar/tests/browser/browser_enter.js
+++ b/browser/components/urlbar/tests/browser/browser_enter.js
@@ -6,6 +6,20 @@
const TEST_VALUE = "example.com/\xF7?\xF7";
const START_VALUE = "example.com/%C3%B7?%C3%B7";
+add_task(async function setup() {
+ const engine = await SearchTestUtils.promiseNewSearchEngine(
+ getRootDirectory(gTestPath) + "searchSuggestionEngine.xml"
+ );
+
+ const defaultEngine = Services.search.defaultEngine;
+ Services.search.defaultEngine = engine;
+
+ registerCleanupFunction(async function() {
+ Services.search.defaultEngine = defaultEngine;
+ });
+});
+
+
add_task(async function returnKeypress() {
info("Simple return keypress");
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, START_VALUE);
@@ -82,12 +96,7 @@ add_task(async function altGrReturnKeypress() {
add_task(async function searchOnEnterNoPick() {
info("Search on Enter without picking a urlbar result");
- let engine = await SearchTestUtils.promiseNewSearchEngine(
- getRootDirectory(gTestPath) + "searchSuggestionEngine.xml"
- );
- let defaultEngine = Services.search.defaultEngine;
- Services.search.defaultEngine = engine;
- // Why is BrowserTestUtils.openNewForegroundTab not causing the bug?
+ // Why is BrowserTestUtils.openNewForegroundTab not causing the bug?
let promiseTabOpened = BrowserTestUtils.waitForEvent(
gBrowser.tabContainer,
"TabOpen"
@@ -95,11 +104,7 @@ add_task(async function searchOnEnterNoPick() {
EventUtils.synthesizeMouseAtCenter(gBrowser.tabContainer.newTabButton, {});
let openEvent = await promiseTabOpened;
let tab = openEvent.target;
- registerCleanupFunction(async function() {
- Services.search.defaultEngine = defaultEngine;
- BrowserTestUtils.removeTab(tab);
- });
-
+
let loadPromise = BrowserTestUtils.browserLoaded(
gBrowser.selectedBrowser,
false,
@@ -120,4 +125,77 @@ add_task(async function searchOnEnterNoPick() {
gURLBar.untrimmedValue,
"The location should have changed"
);
+
+ // Cleanup.
+ BrowserTestUtils.removeTab(tab);
+});
+
+add_task(async function searchOnEnterSoon() {
+ info("Search on Enter as soon as typing a char");
+ const tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ START_VALUE
+ );
+
+ const onLoad = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
+ const onBeforeUnload = SpecialPowers.spawn(
+ gBrowser.selectedBrowser,
+ [],
+ () => {
+ return new Promise(resolve => {
+ content.window.addEventListener("beforeunload", () => {
+ resolve();
+ });
+ });
+ }
+ );
+ const onResult = SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
+ return new Promise(resolve => {
+ content.window.addEventListener("keyup", () => {
+ resolve("keyup");
+ });
+ content.window.addEventListener("unload", () => {
+ resolve("unload");
+ });
+ });
+ });
+
+ // Focus on the input field in urlbar.
+ EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, {});
+ const ownerDocument = gBrowser.selectedBrowser.ownerDocument;
+ is(
+ ownerDocument.activeElement,
+ gURLBar.inputField,
+ "The input field in urlbar has focus"
+ );
+
+ info("Keydown a char and Enter");
+ EventUtils.synthesizeKey("x", { type: "keydown" });
+ EventUtils.synthesizeKey("KEY_Enter", { type: "keydown" });
+
+ // Wait for beforeUnload event in the content.
+ await onBeforeUnload;
+ is(
+ ownerDocument.activeElement,
+ gURLBar.inputField,
+ "The input field in urlbar still has focus"
+ );
+
+ // Keyup both key as soon as beforeUnload event happens.
+ EventUtils.synthesizeKey("x", { type: "keyup" });
+ EventUtils.synthesizeKey("KEY_Enter", { type: "keyup" });
+
+ // Wait for moving the focus.
+ await TestUtils.waitForCondition(
+ () => ownerDocument.activeElement === gBrowser.selectedBrowser
+ );
+ info("The focus is moved to the browser");
+
+ // Check whether keyup event is not captured before unload event happens.
+ const result = await onResult;
+ is(result, "unload", "Keyup event is not captured.");
+
+ // Cleanup.
+ await onLoad;
+ BrowserTestUtils.removeTab(tab);
});
--
2.27.0

View File

@ -88,7 +88,7 @@
Summary: Mozilla Firefox Web browser
Name: firefox
Version: 79.0
Release: 22
Release: 23
URL: https://www.mozilla.org/firefox/
License: MPLv1.1 or GPLv2+ or LGPLv2+
Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}/source/firefox-%{version}.source.tar.xz
@ -201,6 +201,7 @@ Patch657: CVE-2020-26950.patch
Patch658: CVE-2020-26971.patch
Patch659: CVE-2021-29946.patch
Patch660: CVE-2022-34481.patch
Patch661: CVE-2020-26979.patch
%if %{?system_nss}
BuildRequires: pkgconfig(nspr) >= %{nspr_version} pkgconfig(nss) >= %{nss_version}
@ -396,6 +397,7 @@ tar -xf %{SOURCE3}
%patch658 -p1
%patch659 -p1
%patch660 -p1
%patch661 -p1
%{__rm} -f .mozconfig
%{__cp} %{SOURCE10} .mozconfig
@ -844,6 +846,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
%endif
%changelog
* Wed Jun 5 2024 lvfei <lvfei@kylinos.cn> - 79.0-23
- Fix CVE-2020-26979
* Mon May 27 2024 lvfei <lvfei@kylinos.cn> - 79.0-22
- Fix CVE-2022-34481