Firefox · Toolkit
CVE-2026-74952
Logic Error in Toolkit
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
iftoolkit/mozapps/update/common/updatecommon.cpp |
modified | |
iftoolkit/mozapps/update/updater/updater.cpp |
modified |
Files Changed
toolkit/mozapps/update/common/updatecommon.cpptoolkit/mozapps/update/common/updatecommon.htoolkit/mozapps/update/updater/updater.cpp
Patch
diff --git a/toolkit/mozapps/update/common/updatecommon.cpp b/toolkit/mozapps/update/common/updatecommon.cpp
index 05fdf6d60b6..ab967f68c51 100644
--- a/toolkit/mozapps/update/common/updatecommon.cpp
+++ b/toolkit/mozapps/update/common/updatecommon.cpp
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#include "updatedefines.h"
#if defined(XP_WIN)
# include <windows.h>
# include <winioctl.h> // for FSCTL_GET_REPARSE_POINT
@@ -11,6 +12,10 @@
# endif
#endif
+#if defined(XP_MACOSX)
+# include <os/log.h>
+#endif
+
#include <stdio.h>
#include <stdarg.h>
@@ -63,7 +68,10 @@ void UpdateLog::Init(NS_tchar* logFilePath) {
if (dstFilePathLen > 0 && dstFilePathLen < MAXPATHLEN - 1) {
NS_tstrncpy(mDstFilePath, logFilePath, MAXPATHLEN);
#if defined(XP_WIN) || defined(XP_MACOSX)
- logFP = NS_tfopen(mDstFilePath, NS_T("w"));
+ logFP = CreateAndOpenFile(mDstFilePath, false);
+ if (logFP == nullptr) {
+ LogToOS(NS_T("Failed to create FILE*"));
+ }
#else
// On platforms that have an updates directory in the installation directory
// (e.g. platforms other than Windows and Mac) the update log is written to
@@ -87,7 +95,11 @@ void UpdateLog::Finish() {
fflush(logFP);
rewind(logFP);
- FILE* updateLogFP = NS_tfopen(mDstFilePath, NS_T("wb+"));
+ FILE* updateLogFP = CreateAndOpenFile(mDstFilePath, true);
+ if (updateLogFP == nullptr) {
+ return;
+ }
+
while (!feof(logFP)) {
size_t read = fread(buffer, 1, blockSize, logFP);
if (ferror(logFP)) {
@@ -190,6 +202,52 @@ void UpdateLog::WarnPrintf(const char* fmt, ...) {
fflush(logFP);
}
+/**
+ * Creates and opens a file for logging in read/write mode.
+ *
+ * @param filePath The path of the log file.
+ * @param binary If the file should be opened as binary (ignored on
+ * macOS/Linux).
+ * @return a pointer to the FILE struct or nullptr on error.
+ */
+FILE* CreateAndOpenFile(NS_tchar* filePath, bool binary) {
+#ifdef XP_WIN
+ return NS_tfopen(filePath, binary ? NS_T("wb+") : NS_T("w+"));
+#else
+ LogToOS(NS_T("Opening logfile"));
+ NS_tchar* lastSeperator = NS_tstrrchr(filePath, '/');
+ if (lastSeperator == NULL) {
+ // No separator, disable logging.
+ return nullptr;
+ }
+
+ long dirLength = lastSeperator - filePath;
+ if (dirLength < 0 || dirLength >= MAXPATHLEN - 13) {
+ // Too short, or too long. Disable logging.
+ return nullptr;
+ }
+
+ NS_tchar tmpFilePath[MAXPATHLEN] = {L'\0'};
+ NS_tstrncpy(tmpFilePath, filePath, MAXPATHLEN);
+ NS_tstrncpy(tmpFilePath + dirLength, "/temp.XXXXXX", 13);
+
+ int fd = mkstemp(tmpFilePath);
+ if (fd == -1) {
+ LogToOS(NS_T("Failed to open tmp"));
+ return nullptr;
+ }
+
+ if (rename(tmpFilePath, filePath) == -1) {
+ LogToOS(NS_T("Failed to rename"));
+ close(fd);
+ return nullptr;
+ }
+
+ LogToOS(NS_T("Opening file*"));
+ return fdopen(fd, "w+");
+#endif
+}
+
#ifdef XP_WIN
/**
* Determine if a path contains symlinks or junctions to disallowed locations
@@ -474,3 +532,21 @@ bool IsValidFullPath(NS_tchar* origFullPath) {
#endif
return true;
}
+
+#if defined(XP_MACOSX)
+// This is never deallocated by the system
+static os_log_t updaterLogger = os_log_create("org.mozilla.updater", "Updater");
+#endif
+
+/**
+ * Logs a message to the system log for debugging purposes before our log
+ * file has been set up.
+ *
+ * @param message
+ * The message to log.
+ */
+void LogToOS(const NS_tchar* message) {
+#if defined(XP_MACOSX)
+ os_log(updaterLogger, "%{public}s", message);
+#endif
+}
diff --git a/toolkit/mozapps/update/common/updatecommon.h b/toolkit/mozapps/update/common/updatecommon.h
index 9023dc6bda9..be2e552c0d8 100644
--- a/toolkit/mozapps/update/common/updatecommon.h
+++ b/toolkit/mozapps/update/common/updatecommon.h
@@ -35,6 +35,8 @@ class UpdateLog {
bool IsValidFullPath(NS_tchar* fullPath);
bool IsProgramFilesPath(NS_tchar* fullPath);
+FILE* CreateAndOpenFile(NS_tchar* logFilePath, bool binary);
+void LogToOS(const NS_tchar* message);
#define LOG_WARN(args) UpdateLog::GetPrimaryLog().WarnPrintf args
#define LOG(args) UpdateLog::GetPrimaryLog().Printf args
diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp
index f11eae197d8..634935a9ec8 100644
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -2510,7 +2510,7 @@ static bool WriteToFile(const NS_tchar* aFilename, const char* aStatus) {
}
#endif
- AutoFile statusFile(NS_tfopen(statusFilePath, NS_T("wb+")));
+ AutoFile statusFile(CreateAndOpenFile(statusFilePath, true));
if (statusFile == nullptr) {
LOG(("WriteToFile failed to open status file: %d", errno));
return false;
@@ -3303,6 +3303,8 @@ bool ShouldRunSilently(int argc, NS_tchar** argv) {
}
int NS_main(int argc, NS_tchar** argv) {
+ LogToOS(NS_T("Updater started"));
+
// We may need to tweak our argument list when we launch the Second Updater
// Invocation (SUI), so we are going to make a copy of our arguments to
// modify.
@@ -3339,6 +3341,7 @@ int NS_main(int argc, NS_tchar** argv) {
#ifdef XP_MACOSX
if (argc > 2 && NS_tstrcmp(argv[1], NS_T("--openAppBundle")) == 0) {
+ LogToOS(NS_T("Opening App Bundle"));
// We have been asked to open a .app bundle. The path to the .app bundle and
// any command line arguments have been passed to us as arguments after
// "--openAppBundle", so remove the first two arguments and launch the .app
@@ -3398,6 +3401,7 @@ int NS_main(int argc, NS_tchar** argv) {
#ifdef XP_MACOSX
if (isElevated) {
+ LogToOS(NS_T("Updater is elevated"));
if (!ObtainUpdaterArguments(&argc, &argv, &gMARStrings)) {
// Won't actually get here because ObtainUpdaterArguments will terminate
// the current process on failure.
Loading diff…
References
On This Page