зеркало из https://github.com/mozilla/gecko-dev.git
Client code - Bug 1342742 - check that the app update patch dir, install dir, and working dir paths are valid. r=mhowell
--HG-- rename : toolkit/mozapps/update/common/updatelogging.cpp => toolkit/mozapps/update/common/updatecommon.cpp rename : toolkit/mozapps/update/common/updatelogging.h => toolkit/mozapps/update/common/updatecommon.h
This commit is contained in:
Родитель
c9357cb3b0
Коммит
0de416e483
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <windows.h>
|
||||
#include "updatelogging.h"
|
||||
#include "updatecommon.h"
|
||||
|
||||
BOOL PathAppendSafe(LPWSTR base, LPCWSTR extra);
|
||||
BOOL VerifySameFiles(LPCWSTR file1Path, LPCWSTR file2Path, BOOL &sameContent);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "registrycertificates.h"
|
||||
#include "uachelper.h"
|
||||
#include "updatehelper.h"
|
||||
#include "pathhash.h"
|
||||
#include "errors.h"
|
||||
|
||||
// Wait 15 minutes for an update operation to run at most.
|
||||
|
@ -32,6 +33,7 @@ wchar_t* MakeCommandLine(int argc, wchar_t** argv);
|
|||
BOOL WriteStatusFailure(LPCWSTR updateDirPath, int errorCode);
|
||||
BOOL PathGetSiblingFilePath(LPWSTR destinationBuffer, LPCWSTR siblingFilePath,
|
||||
LPCWSTR newFileName);
|
||||
BOOL DoesFallbackKeyExist();
|
||||
|
||||
/*
|
||||
* Read the update.status file and sets isApplying to true if
|
||||
|
@ -415,8 +417,7 @@ ProcessSoftwareUpdateCommand(DWORD argc, LPWSTR *argv)
|
|||
// We can only update update.status if argv[1] exists. argv[1] is
|
||||
// the directory where the update.status file exists.
|
||||
if (argc < 2 ||
|
||||
!WriteStatusFailure(argv[1],
|
||||
SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS)) {
|
||||
!WriteStatusFailure(argv[1], SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS)) {
|
||||
LOG_WARN(("Could not write update.status service update failure. (%d)",
|
||||
GetLastError()));
|
||||
}
|
||||
|
@ -426,8 +427,7 @@ ProcessSoftwareUpdateCommand(DWORD argc, LPWSTR *argv)
|
|||
WCHAR installDir[MAX_PATH + 1] = {L'\0'};
|
||||
if (!GetInstallationDir(argc, argv, installDir)) {
|
||||
LOG_WARN(("Could not get the installation directory"));
|
||||
if (!WriteStatusFailure(argv[1],
|
||||
SERVICE_INSTALLDIR_ERROR)) {
|
||||
if (!WriteStatusFailure(argv[1], SERVICE_INSTALLDIR_ERROR)) {
|
||||
LOG_WARN(("Could not write update.status for GetInstallationDir failure."));
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -587,6 +587,73 @@ ExecuteServiceCommand(int argc, LPWSTR *argv)
|
|||
|
||||
BOOL result = FALSE;
|
||||
if (!lstrcmpi(argv[2], L"software-update")) {
|
||||
// This check is also performed in updater.cpp and is performed here
|
||||
// as well since the maintenance service can be called directly.
|
||||
if (argc < 4 || !IsValidFullPath(argv[4])) {
|
||||
// Since the status file is written to the patch directory and the patch
|
||||
// directory is invalid don't write the status file.
|
||||
LOG_WARN(("The patch directory path is not valid for this application."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// This check is also performed in updater.cpp and is performed here
|
||||
// as well since the maintenance service can be called directly.
|
||||
if (argc < 5 || !IsValidFullPath(argv[5])) {
|
||||
LOG_WARN(("The install directory path is not valid for this application."));
|
||||
if (!WriteStatusFailure(argv[4], SERVICE_INVALID_INSTALL_DIR_PATH_ERROR)) {
|
||||
LOG_WARN(("Could not write update.status for previous failure."));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!IsOldCommandline(argc - 3, argv + 3)) {
|
||||
// This check is also performed in updater.cpp and is performed here
|
||||
// as well since the maintenance service can be called directly.
|
||||
if (argc < 6 || !IsValidFullPath(argv[6])) {
|
||||
LOG_WARN(("The working directory path is not valid for this application."));
|
||||
if (!WriteStatusFailure(argv[4], SERVICE_INVALID_WORKING_DIR_PATH_ERROR)) {
|
||||
LOG_WARN(("Could not write update.status for previous failure."));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// These checks are also performed in updater.cpp and is performed here
|
||||
// as well since the maintenance service can be called directly.
|
||||
if (_wcsnicmp(argv[6], argv[5], MAX_PATH) != 0) {
|
||||
if (wcscmp(argv[7], L"-1") != 0 && !wcsstr(argv[7], L"/replace")) {
|
||||
LOG_WARN(("Installation directory and working directory must be the "
|
||||
"same for non-staged updates. Exiting."));
|
||||
if (!WriteStatusFailure(argv[4], SERVICE_INVALID_APPLYTO_DIR_ERROR)) {
|
||||
LOG_WARN(("Could not write update.status for previous failure."));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NS_tchar workingDirParent[MAX_PATH];
|
||||
NS_tsnprintf(workingDirParent,
|
||||
sizeof(workingDirParent) / sizeof(workingDirParent[0]),
|
||||
NS_T("%s"), argv[6]);
|
||||
if (!PathRemoveFileSpecW(workingDirParent)) {
|
||||
LOG_WARN(("Couldn't remove file spec when attempting to verify the "
|
||||
"working directory path. (%d)", GetLastError()));
|
||||
if (!WriteStatusFailure(argv[4], REMOVE_FILE_SPEC_ERROR)) {
|
||||
LOG_WARN(("Could not write update.status for previous failure."));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (_wcsnicmp(workingDirParent, argv[5], MAX_PATH) != 0) {
|
||||
LOG_WARN(("The apply-to directory must be the same as or "
|
||||
"a child of the installation directory! Exiting."));
|
||||
if (!WriteStatusFailure(argv[4], SERVICE_INVALID_APPLYTO_DIR_STAGED_ERROR)) {
|
||||
LOG_WARN(("Could not write update.status for previous failure."));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Use the passed in command line arguments for the update, except for the
|
||||
// path to updater.exe. We always look for updater.exe in the installation
|
||||
// directory, then we copy updater.exe to a the directory of the
|
||||
|
@ -596,12 +663,37 @@ ExecuteServiceCommand(int argc, LPWSTR *argv)
|
|||
WCHAR installDir[MAX_PATH + 1] = { L'\0' };
|
||||
if (!GetInstallationDir(argc - 3, argv + 3, installDir)) {
|
||||
LOG_WARN(("Could not get the installation directory"));
|
||||
if (!WriteStatusFailure(argv[1],
|
||||
SERVICE_INSTALLDIR_ERROR)) {
|
||||
LOG_WARN(("Could not write update.status for GetInstallationDir failure."));
|
||||
if (!WriteStatusFailure(argv[4], SERVICE_INSTALLDIR_ERROR)) {
|
||||
LOG_WARN(("Could not write update.status for previous failure."));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!DoesFallbackKeyExist()) {
|
||||
WCHAR maintenanceServiceKey[MAX_PATH + 1];
|
||||
if (CalculateRegistryPathFromFilePath(installDir, maintenanceServiceKey)) {
|
||||
LOG(("Checking for Maintenance Service registry. key: '%ls'",
|
||||
maintenanceServiceKey));
|
||||
HKEY baseKey = nullptr;
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
maintenanceServiceKey, 0,
|
||||
KEY_READ | KEY_WOW64_64KEY,
|
||||
&baseKey) != ERROR_SUCCESS) {
|
||||
LOG_WARN(("The maintenance service registry key does not exist."));
|
||||
if (!WriteStatusFailure(argv[4], SERVICE_INSTALL_DIR_REG_ERROR)) {
|
||||
LOG_WARN(("Could not write update.status for previous failure."));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
RegCloseKey(baseKey);
|
||||
} else {
|
||||
if (!WriteStatusFailure(argv[4], SERVICE_CALC_REG_PATH_ERROR)) {
|
||||
LOG_WARN(("Could not write update.status for previous failure."));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
WCHAR installDirUpdater[MAX_PATH + 1] = { L'\0' };
|
||||
wcsncpy(installDirUpdater, installDir, MAX_PATH);
|
||||
if (!PathAppendSafe(installDirUpdater, L"updater.exe")) {
|
||||
|
@ -609,7 +701,7 @@ ExecuteServiceCommand(int argc, LPWSTR *argv)
|
|||
result = FALSE;
|
||||
}
|
||||
|
||||
result = UpdaterIsValid(installDirUpdater, installDir, argv[5]);
|
||||
result = UpdaterIsValid(installDirUpdater, installDir, argv[4]);
|
||||
|
||||
WCHAR secureUpdaterPath[MAX_PATH + 1] = { L'\0' };
|
||||
if (result) {
|
||||
|
@ -617,7 +709,7 @@ ExecuteServiceCommand(int argc, LPWSTR *argv)
|
|||
}
|
||||
if (result) {
|
||||
LOG(("Passed in path: '%ls'; Using this path for updating: '%ls'.",
|
||||
installDirUpdater, secureUpdaterPath));
|
||||
installDirUpdater, secureUpdaterPath));
|
||||
DeleteSecureUpdater(secureUpdaterPath);
|
||||
result = CopyFileW(installDirUpdater, secureUpdaterPath, FALSE);
|
||||
}
|
||||
|
@ -625,8 +717,7 @@ ExecuteServiceCommand(int argc, LPWSTR *argv)
|
|||
if (!result) {
|
||||
LOG_WARN(("Could not copy path to secure location. (%d)",
|
||||
GetLastError()));
|
||||
if (argc > 4 && !WriteStatusFailure(argv[4],
|
||||
SERVICE_COULD_NOT_COPY_UPDATER)) {
|
||||
if (!WriteStatusFailure(argv[4], SERVICE_COULD_NOT_COPY_UPDATER)) {
|
||||
LOG_WARN(("Could not write update.status could not copy updater error"));
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <wintrust.h>
|
||||
|
||||
#include "certificatecheck.h"
|
||||
#include "updatelogging.h"
|
||||
#include "updatecommon.h"
|
||||
|
||||
static const int ENCODING = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#define MAR_CHANNEL_MISMATCH_ERROR 22
|
||||
#define VERSION_DOWNGRADE_ERROR 23
|
||||
|
||||
// Error codes 24-33 and 49-51 are for the Windows maintenance service.
|
||||
// Error codes 24-33 and 49-57 are for the Windows maintenance service.
|
||||
#define SERVICE_UPDATER_COULD_NOT_BE_STARTED 24
|
||||
#define SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS 25
|
||||
#define SERVICE_UPDATER_SIGN_ERROR 26
|
||||
|
@ -66,10 +66,16 @@
|
|||
#define DELETE_ERROR_EXPECTED_FILE 47
|
||||
#define RENAME_ERROR_EXPECTED_FILE 48
|
||||
|
||||
// Error codes 24-33 and 49-51 are for the Windows maintenance service.
|
||||
// Error codes 24-33 and 49-57 are for the Windows maintenance service.
|
||||
#define SERVICE_COULD_NOT_COPY_UPDATER 49
|
||||
#define SERVICE_STILL_APPLYING_TERMINATED 50
|
||||
#define SERVICE_STILL_APPLYING_NO_EXIT_CODE 51
|
||||
#define SERVICE_INVALID_APPLYTO_DIR_STAGED_ERROR 52
|
||||
#define SERVICE_CALC_REG_PATH_ERROR 53
|
||||
#define SERVICE_INVALID_APPLYTO_DIR_ERROR 54
|
||||
#define SERVICE_INVALID_INSTALL_DIR_PATH_ERROR 55
|
||||
#define SERVICE_INVALID_WORKING_DIR_PATH_ERROR 56
|
||||
#define SERVICE_INSTALL_DIR_REG_ERROR 57
|
||||
|
||||
#define WRITE_ERROR_FILE_COPY 61
|
||||
#define WRITE_ERROR_DELETE_FILE 62
|
||||
|
@ -85,6 +91,8 @@
|
|||
#define INVALID_APPLYTO_DIR_STAGED_ERROR 72
|
||||
#define LOCK_ERROR_PATCH_FILE 73
|
||||
#define INVALID_APPLYTO_DIR_ERROR 74
|
||||
#define INVALID_INSTALL_DIR_PATH_ERROR 75
|
||||
#define INVALID_WORKING_DIR_PATH_ERROR 76
|
||||
|
||||
// Error codes 80 through 99 are reserved for nsUpdateService.js
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
EXPORTS += [
|
||||
'readstrings.h',
|
||||
'updatecommon.h',
|
||||
'updatedefines.h',
|
||||
'updatelogging.h',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "registrycertificates.h"
|
||||
#include "pathhash.h"
|
||||
#include "updatelogging.h"
|
||||
#include "updatecommon.h"
|
||||
#include "updatehelper.h"
|
||||
#define MAX_KEY_LENGTH 255
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
|
||||
sources += [
|
||||
'readstrings.cpp',
|
||||
'updatelogging.cpp',
|
||||
'updatecommon.cpp',
|
||||
]
|
||||
|
||||
SOURCES += sorted(['%s/%s' % (srcdir, s) for s in sources])
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <windows.h>
|
||||
#include <wtsapi32.h>
|
||||
#include "uachelper.h"
|
||||
#include "updatelogging.h"
|
||||
#include "updatecommon.h"
|
||||
|
||||
// See the MSDN documentation with title: Privilege Constants
|
||||
// At the time of this writing, this documentation is located at:
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "updatelogging.h"
|
||||
#include "updatecommon.h"
|
||||
|
||||
UpdateLog::UpdateLog() : logFP(nullptr)
|
||||
{
|
||||
|
@ -34,12 +34,13 @@ void UpdateLog::Init(NS_tchar* sourcePath,
|
|||
(dstFilePathLen <
|
||||
static_cast<int>(sizeof(mDstFilePath)/sizeof(mDstFilePath[0])))) {
|
||||
#ifdef XP_WIN
|
||||
GetTempFileNameW(sourcePath, L"log", 0, mTmpFilePath);
|
||||
logFP = NS_tfopen(mTmpFilePath, NS_T("w"));
|
||||
if (GetTempFileNameW(sourcePath, L"log", 0, mTmpFilePath) != 0) {
|
||||
logFP = NS_tfopen(mTmpFilePath, NS_T("w"));
|
||||
|
||||
// Delete this file now so it is possible to tell from the unelevated
|
||||
// updater process if the elevated updater process has written the log.
|
||||
DeleteFileW(mDstFilePath);
|
||||
// Delete this file now so it is possible to tell from the unelevated
|
||||
// updater process if the elevated updater process has written the log.
|
||||
DeleteFileW(mDstFilePath);
|
||||
}
|
||||
#elif XP_MACOSX
|
||||
logFP = NS_tfopen(mDstFilePath, NS_T("w"));
|
||||
#else
|
||||
|
@ -145,3 +146,68 @@ void UpdateLog::WarnPrintf(const char *fmt, ... )
|
|||
fprintf(logFP, "***\n");
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs checks of a full path for validity for this application.
|
||||
*
|
||||
* @param origFullPath
|
||||
* The full path to check.
|
||||
* @return true if the path is valid for this application and false otherwise.
|
||||
*/
|
||||
bool
|
||||
IsValidFullPath(NS_tchar* origFullPath)
|
||||
{
|
||||
// Subtract 1 from MAXPATHLEN for null termination.
|
||||
if (NS_tstrlen(origFullPath) > MAXPATHLEN - 1) {
|
||||
// The path is longer than acceptable for this application.
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
NS_tchar testPath[MAXPATHLEN] = {NS_T('\0')};
|
||||
// GetFullPathNameW will replace / with \ which PathCanonicalizeW requires.
|
||||
if (GetFullPathNameW(origFullPath, MAXPATHLEN, testPath, nullptr) == 0) {
|
||||
// Unable to get the full name for the path (e.g. invalid path).
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_tchar canonicalPath[MAXPATHLEN] = {NS_T('\0')};
|
||||
if (!PathCanonicalizeW(canonicalPath, testPath)) {
|
||||
// Path could not be canonicalized (e.g. invalid path).
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the path passed in resolves to a differerent path.
|
||||
if (NS_tstricmp(origFullPath, canonicalPath) != 0) {
|
||||
// Case insensitive string comparison between the supplied path and the
|
||||
// canonical path are not equal. This will prevent directory traversal and
|
||||
// the use of / in paths since they are converted to \.
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_tstrncpy(testPath, origFullPath, MAXPATHLEN);
|
||||
if (!PathStripToRootW(testPath)) {
|
||||
// It should always be possible to strip a valid path to its root.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (origFullPath[0] == NS_T('\\')) {
|
||||
// Only allow UNC server share paths.
|
||||
if (!PathIsUNCServerShareW(testPath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Only allow full paths.
|
||||
if (origFullPath[0] != NS_T('/')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The path must not traverse directories
|
||||
if (NS_tstrstr(origFullPath, NS_T("..")) != nullptr ||
|
||||
NS_tstrstr(origFullPath, NS_T("./")) != nullptr) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
|
@ -2,8 +2,8 @@
|
|||
* 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/. */
|
||||
|
||||
#ifndef UPDATELOGGING_H
|
||||
#define UPDATELOGGING_H
|
||||
#ifndef UPDATECOMMON_H
|
||||
#define UPDATECOMMON_H
|
||||
|
||||
#include "updatedefines.h"
|
||||
#include <stdio.h>
|
||||
|
@ -35,6 +35,8 @@ protected:
|
|||
NS_tchar mDstFilePath[MAXPATHLEN];
|
||||
};
|
||||
|
||||
bool IsValidFullPath(NS_tchar* fullPath);
|
||||
|
||||
#define LOG_WARN(args) UpdateLog::GetPrimaryLog().WarnPrintf args
|
||||
#define LOG(args) UpdateLog::GetPrimaryLog().Printf args
|
||||
#define LogInit(PATHNAME_, FILENAME_) \
|
|
@ -273,7 +273,9 @@ WriteStatusFailure(LPCWSTR updateDirPath, int errorCode)
|
|||
// The temp file is not removed on failure since there is client code that
|
||||
// will remove it.
|
||||
WCHAR tmpUpdateStatusFilePath[MAX_PATH + 1] = { L'\0' };
|
||||
GetTempFileNameW(updateDirPath, L"svc", 0, tmpUpdateStatusFilePath);
|
||||
if (GetTempFileNameW(updateDirPath, L"svc", 0, tmpUpdateStatusFilePath) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HANDLE tmpStatusFile = CreateFileW(tmpUpdateStatusFilePath, GENERIC_WRITE, 0,
|
||||
nullptr, CREATE_ALWAYS, 0, nullptr);
|
||||
|
|
|
@ -79,6 +79,13 @@ LaunchMacPostProcess(const char* aAppBundle)
|
|||
return;
|
||||
}
|
||||
|
||||
// The path must not traverse directories and it must be a relative path.
|
||||
if ([exeRelPath rangeOfString:@".."].location != NSNotFound ||
|
||||
[exeRelPath rangeOfString:@"./"].location != NSNotFound ||
|
||||
[exeRelPath rangeOfString:@"/"].location == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString* exeFullPath = [NSString stringWithUTF8String:aAppBundle];
|
||||
exeFullPath = [exeFullPath stringByAppendingPathComponent:exeRelPath];
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#include <errno.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "updatelogging.h"
|
||||
#include "updatecommon.h"
|
||||
#ifdef XP_MACOSX
|
||||
#include "updaterfileutils_osx.h"
|
||||
#endif // XP_MACOSX
|
||||
|
@ -281,7 +281,7 @@ private:
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static NS_tchar* gPatchDirPath;
|
||||
static NS_tchar gPatchDirPath[MAXPATHLEN];
|
||||
static NS_tchar gInstallDirPath[MAXPATHLEN];
|
||||
static NS_tchar gWorkingDirPath[MAXPATHLEN];
|
||||
static ArchiveReader gArchiveReader;
|
||||
|
@ -1972,8 +1972,20 @@ LaunchWinPostProcess(const WCHAR *installationDir,
|
|||
return false;
|
||||
}
|
||||
|
||||
// Verify that exeFile doesn't contain relative paths
|
||||
if (wcsstr(exefile, L"..") != nullptr) {
|
||||
// The relative path must not contain directory traversals, current directory,
|
||||
// or colons.
|
||||
if (wcsstr(exefile, L"..") != nullptr ||
|
||||
wcsstr(exefile, L"./") != nullptr ||
|
||||
wcsstr(exefile, L".\\") != nullptr ||
|
||||
wcsstr(exefile, L":") != nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The relative path must not start with a decimal point, backslash, or
|
||||
// forward slash.
|
||||
if (exefile[0] == L'.' ||
|
||||
exefile[0] == L'\\' ||
|
||||
exefile[0] == L'/') {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1983,6 +1995,10 @@ LaunchWinPostProcess(const WCHAR *installationDir,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!IsValidFullPath(exefullpath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !defined(TEST_UPDATER) && defined(MOZ_MAINTENANCE_SERVICE)
|
||||
if (sUsingService &&
|
||||
!DoesBinaryMatchAllowedCertificates(installationDir, exefullpath)) {
|
||||
|
@ -2089,7 +2105,9 @@ WriteStatusFile(const char* aStatus)
|
|||
#if defined(XP_WIN)
|
||||
// The temp file is not removed on failure since there is client code that
|
||||
// will remove it.
|
||||
GetTempFileNameW(gPatchDirPath, L"sta", 0, filename);
|
||||
if (GetTempFileNameW(gPatchDirPath, L"sta", 0, filename) == 0) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]),
|
||||
NS_T("%s/update.status"), gPatchDirPath);
|
||||
|
@ -2720,9 +2738,38 @@ int NS_main(int argc, NS_tchar **argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// This check is also performed in workmonitor.cpp since the maintenance
|
||||
// service can be called directly.
|
||||
if (!IsValidFullPath(argv[1])) {
|
||||
// Since the status file is written to the patch directory and the patch
|
||||
// directory is invalid don't write the status file.
|
||||
fprintf(stderr, "The patch directory path is not valid for this " \
|
||||
"application (" LOG_S ")\n", argv[1]);
|
||||
#ifdef XP_MACOSX
|
||||
if (isElevated) {
|
||||
freeArguments(argc, argv);
|
||||
CleanupElevatedMacUpdate(true);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
// The directory containing the update information.
|
||||
gPatchDirPath = argv[1];
|
||||
NS_tstrncpy(gPatchDirPath, argv[1], MAXPATHLEN);
|
||||
|
||||
// This check is also performed in workmonitor.cpp since the maintenance
|
||||
// service can be called directly.
|
||||
if (!IsValidFullPath(argv[2])) {
|
||||
WriteStatusFile(INVALID_INSTALL_DIR_PATH_ERROR);
|
||||
fprintf(stderr, "The install directory path is not valid for this " \
|
||||
"application (" LOG_S ")\n", argv[2]);
|
||||
#ifdef XP_MACOSX
|
||||
if (isElevated) {
|
||||
freeArguments(argc, argv);
|
||||
CleanupElevatedMacUpdate(true);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
// The directory we're going to update to.
|
||||
// We copy this string because we need to remove trailing slashes. The C++
|
||||
// standard says that it's always safe to write to strings pointed to by argv
|
||||
|
@ -2795,6 +2842,20 @@ int NS_main(int argc, NS_tchar **argv)
|
|||
}
|
||||
}
|
||||
|
||||
// This check is also performed in workmonitor.cpp since the maintenance
|
||||
// service can be called directly.
|
||||
if (!IsValidFullPath(argv[3])) {
|
||||
WriteStatusFile(INVALID_WORKING_DIR_PATH_ERROR);
|
||||
fprintf(stderr, "The working directory path is not valid for this " \
|
||||
"application (" LOG_S ")\n", argv[3]);
|
||||
#ifdef XP_MACOSX
|
||||
if (isElevated) {
|
||||
freeArguments(argc, argv);
|
||||
CleanupElevatedMacUpdate(true);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
// The directory we're going to update to.
|
||||
// We copy this string because we need to remove trailing slashes. The C++
|
||||
// standard says that it's always safe to write to strings pointed to by argv
|
||||
|
@ -2851,6 +2912,8 @@ int NS_main(int argc, NS_tchar **argv)
|
|||
LOG(("WORKING DIRECTORY " LOG_S, gWorkingDirPath));
|
||||
|
||||
#if defined(XP_WIN)
|
||||
// These checks are also performed in workmonitor.cpp since the maintenance
|
||||
// service can be called directly.
|
||||
if (_wcsnicmp(gWorkingDirPath, gInstallDirPath, MAX_PATH) != 0) {
|
||||
if (!sStagedUpdate && !sReplaceRequest) {
|
||||
WriteStatusFile(INVALID_APPLYTO_DIR_ERROR);
|
||||
|
|
Загрузка…
Ссылка в новой задаче