From e38af9549452e0a59d5b65ad6ca7f19fc078f32b Mon Sep 17 00:00:00 2001 From: lvfei Date: Mon, 5 Aug 2024 17:48:58 +0800 Subject: [PATCH] Fix CVE-2022-29912 --- CVE-2022-29912.patch | 184 +++++++++++++++++++++++++++++++++++++++++++ firefox.spec | 7 +- 2 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 CVE-2022-29912.patch diff --git a/CVE-2022-29912.patch b/CVE-2022-29912.patch new file mode 100644 index 0000000..62d4ad0 --- /dev/null +++ b/CVE-2022-29912.patch @@ -0,0 +1,184 @@ +From caacc07b2d65aa1ba292681cc4f4f607bf9161dc Mon Sep 17 00:00:00 2001 +From: Gijs Kruitbosch +Date: Thu, 24 Mar 2022 14:35:35 +0000 (2022-03-24) +Subject: [PATCH] CVE-2022-29912 + +--- + browser/actors/AboutReaderParent.jsm | 7 ++ + toolkit/components/reader/AboutReader.jsm | 7 +- + toolkit/components/reader/ReaderMode.jsm | 82 ++++++++--------------- + 3 files changed, 40 insertions(+), 56 deletions(-) + +diff --git a/browser/actors/AboutReaderParent.jsm b/browser/actors/AboutReaderParent.jsm +index 20bb1b3be3..9c5fd812f7 100644 +--- a/browser/actors/AboutReaderParent.jsm ++++ b/browser/actors/AboutReaderParent.jsm +@@ -155,6 +155,13 @@ class AboutReaderParent extends JSWindowActorParent { + this.callListeners(message); + break; + } ++ ++ case "RedirectTo": { ++ gCachedArticles.set(message.data.newURL, message.data.article); ++ // This is setup as a query so we can navigate the page after we've ++ // cached the relevant info in the parent. ++ return true; ++ } + + default: + this.callListeners(message); +diff --git a/toolkit/components/reader/AboutReader.jsm b/toolkit/components/reader/AboutReader.jsm +index 4904b525fb..3a1e95411c 100644 +--- a/toolkit/components/reader/AboutReader.jsm ++++ b/toolkit/components/reader/AboutReader.jsm +@@ -743,7 +743,12 @@ AboutReader.prototype = { + try { + article = await ReaderMode.downloadAndParseDocument(url); + } catch (e) { +- if (e && e.newURL) { ++ if (e?.newURL && this._actor) { ++ await this._actor.sendQuery("RedirectTo", { ++ newURL: e.newURL, ++ article: e.article, ++ }); ++ + let readerURL = "about:reader?url=" + encodeURIComponent(e.newURL); + this._win.location.replace(readerURL); + return; +diff --git a/toolkit/components/reader/ReaderMode.jsm b/toolkit/components/reader/ReaderMode.jsm +index 57694c9467..33b80f2c67 100644 +--- a/toolkit/components/reader/ReaderMode.jsm ++++ b/toolkit/components/reader/ReaderMode.jsm +@@ -80,7 +80,7 @@ var ReaderMode = { + */ + enterReaderMode(docShell, win) { + let url = win.document.location.href; +- let readerURL = "about:reader?url=" + encodeURIComponent(url); ++ let originalURL = this.getOriginalUrl(url); + let webNav = docShell.QueryInterface(Ci.nsIWebNavigation); + let sh = webNav.sessionHistory; + if (webNav.canGoForward) { +@@ -181,8 +181,8 @@ var ReaderMode = { + }, + + getOriginalUrlObjectForDisplay(url) { +- let originalUrl = this.getOriginalUrl(url); +- if (originalUrl) { ++ let originalUrl = this.getOriginalUrl(url); ++ if (originalUrl) { + let uriObj; + try { + uriObj = Services.uriFixup.createFixupURI( +@@ -229,10 +229,11 @@ var ReaderMode = { + * @resolves JS object representing the article, or null if no article is found. + */ + async downloadAndParseDocument(url) { +- let doc = await this._downloadDocument(url); +- if (!doc) { ++ let result = await this._downloadDocument(url, docContentType); ++ if (!result?.doc) { + return null; + } ++ let { doc, newURL } = result; + if ( + !Readerable.shouldCheckUri(doc.documentURIObject) || + !Readerable.shouldCheckUri(doc.baseURIObject, true) +@@ -241,7 +242,14 @@ var ReaderMode = { + return null; + } + +- return this._readerParse(doc); ++ let article = await this._readerParse(doc); ++ // If we have to redirect, reject to the caller with the parsed article, ++ // so we can update the URL before displaying it. ++ if (newURL) { ++ return Promise.reject({ newURL, article }); ++ } ++ // Otherwise, we can just continue with the article. ++ return article; + }, + + _downloadDocument(url) { +@@ -276,49 +284,7 @@ var ReaderMode = { + histogram.add(DOWNLOAD_ERROR_NO_DOC); + return; + } +- +- // Manually follow a meta refresh tag if one exists. +- let meta = doc.querySelector("meta[http-equiv=refresh]"); +- if (meta) { +- let content = meta.getAttribute("content"); +- if (content) { +- let urlIndex = content.toUpperCase().indexOf("URL="); +- if (urlIndex > -1) { +- let baseURI = Services.io.newURI(url); +- let newURI = Services.io.newURI( +- content.substring(urlIndex + 4), +- null, +- baseURI +- ); +- let newURL = newURI.spec; +- let ssm = Services.scriptSecurityManager; +- let flags = +- ssm.LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT | +- ssm.DISALLOW_INHERIT_PRINCIPAL; +- try { +- ssm.checkLoadURIStrWithPrincipal( +- doc.nodePrincipal, +- newURL, +- flags +- ); +- } catch (ex) { +- let errorMsg = +- "Reader mode disallowed meta refresh (reason: " + ex + ")."; +- +- if (Services.prefs.getBoolPref("reader.errors.includeURLs")) { +- errorMsg += " Refresh target URI: '" + newURL + "'."; +- } +- reject(errorMsg); +- return; +- } +- // Otherwise, pass an object indicating our new URL: +- if (!baseURI.equalsExceptRef(newURI)) { +- reject({ newURL }); +- return; +- } +- } +- } +- } ++ + let responseURL = xhr.responseURL; + let givenURL = url; + // Convert these to real URIs to make sure the escaping (or lack +@@ -332,16 +298,22 @@ var ReaderMode = { + givenURL = Services.io.newURI(givenURL).specIgnoringRef; + } catch (ex) { + /* Ignore errors - we'll use what we had before */ ++ } ++ if (xhr.responseType != "document") { ++ let initialText = doc; ++ let parser = new DOMParser(); ++ doc = parser.parseFromString(`
`, "text/html");
++          doc.querySelector("pre").textContent = initialText;
+         }
+ 
++        // We treat redirects as download successes here:
++        histogram.add(DOWNLOAD_SUCCESS);
++        let result = { doc };
+         if (responseURL != givenURL) {
+-          // We were redirected without a meta refresh tag.
+-          // Force redirect to the correct place:
+-          reject({ newURL: xhr.responseURL });
+-          return;
++          result.newURL = xhr.responseURL;
+         }
+-        resolve(doc);
+-        histogram.add(DOWNLOAD_SUCCESS);
++
++        resolve(result);
+       };
+       xhr.send();
+     });
+-- 
+2.33.0
+
diff --git a/firefox.spec b/firefox.spec
index b2e17db..edb5325 100644
--- a/firefox.spec
+++ b/firefox.spec
@@ -88,7 +88,7 @@
 Summary:             Mozilla Firefox Web browser
 Name:                firefox
 Version:             79.0
-Release:             29
+Release:             30
 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
@@ -210,6 +210,7 @@ Patch666:            CVE-2021-23954.patch
 Patch667:            CVE-2021-29984.patch
 Patch668:            CVE-2021-29988.patch
 Patch669:            CVE-2021-23998.patch
+Patch670:            CVE-2022-29912.patch
 
 %if %{?system_nss}
 BuildRequires:       pkgconfig(nspr) >= %{nspr_version} pkgconfig(nss) >= %{nss_version}
@@ -414,6 +415,7 @@ tar -xf %{SOURCE3}
 %patch667 -p1
 %patch668 -p1
 %patch669 -p1
+%patch670 -p1
 
 %{__rm} -f .mozconfig
 %{__cp} %{SOURCE10} .mozconfig
@@ -862,6 +864,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
 %endif
 
 %changelog
+* Sat Aug 03 2024 lvfei  - 79.0-30
+- Fix CVE-2022-29912.patch
+
 * Mon Jul 22 2024 technology208  - 79.0-29
 - Fix CVE-2021-23998
 
-- 
Gitee