diff --git a/CHANGELOG.md b/CHANGELOG.md index a0b4dbc5..9a137f2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,15 @@ This project adheres to [Semantic Versioning](http://semver.org/). + +## [1.0.13 / 5.55.13] - 2022-03-07 + + +### Fixed +- FIXED SECURITY ISSUE: Hard link creation was not properly filtered (thanks Diversenok) +- fixed issue with checking the certificate entry. + + ## [1.0.12 / 5.55.12] - 2022-03-02 ### Added diff --git a/Sandboxie/common/my_version.h b/Sandboxie/common/my_version.h index 76e26601..206a8da2 100644 --- a/Sandboxie/common/my_version.h +++ b/Sandboxie/common/my_version.h @@ -21,8 +21,8 @@ #ifndef _MY_VERSION_H #define _MY_VERSION_H -#define MY_VERSION_BINARY 5,55,12 -#define MY_VERSION_STRING "5.55.12" +#define MY_VERSION_BINARY 5,55,13 +#define MY_VERSION_STRING "5.55.13" #define MY_VERSION_COMPAT "5.55.0" // this refers to the driver ABI compatibility // These #defines are used by either Resource Compiler or NSIS installer diff --git a/Sandboxie/core/drv/driver.h b/Sandboxie/core/drv/driver.h index f792fe60..da7a9563 100644 --- a/Sandboxie/core/drv/driver.h +++ b/Sandboxie/core/drv/driver.h @@ -73,8 +73,6 @@ #define HOOK_WIN32K -//new FILE_INFORMATION_CLASS type not defined in current wdm.h used in windows 10 FCU -#define SB_FileRenameInformationEx 65 //--------------------------------------------------------------------------- // Structures and Types //--------------------------------------------------------------------------- diff --git a/Sandboxie/core/drv/file_flt.c b/Sandboxie/core/drv/file_flt.c index 8e7edd19..d7efb6cb 100644 --- a/Sandboxie/core/drv/file_flt.c +++ b/Sandboxie/core/drv/file_flt.c @@ -316,7 +316,8 @@ _FX FLT_PREOP_CALLBACK_STATUS File_PreOperation( // we allow IRP_MJ_SET_INFORMATION to pass except for these 3 if ((Iopb->Parameters.SetFileInformation.FileInformationClass != FileRenameInformation) && (Iopb->Parameters.SetFileInformation.FileInformationClass != FileLinkInformation) && - (Iopb->Parameters.SetFileInformation.FileInformationClass != SB_FileRenameInformationEx)) + (Iopb->Parameters.SetFileInformation.FileInformationClass != FileLinkInformationEx) && + (Iopb->Parameters.SetFileInformation.FileInformationClass != FileRenameInformationEx)) goto finish; @@ -444,11 +445,34 @@ _FX FLT_PREOP_CALLBACK_STATUS File_PreOperation( if (Iopb->MajorFunction == IRP_MJ_SET_INFORMATION) { // Do not allow hard links outside the sandbox - if (Iopb->Parameters.SetFileInformation.FileInformationClass == FileLinkInformation) { - if(Iopb->Parameters.SetFileInformation.ParentOfTarget && - !Box_IsBoxedPath(proc->box, file, &Iopb->Parameters.SetFileInformation.ParentOfTarget->FileName)) { + if (Iopb->Parameters.SetFileInformation.FileInformationClass == FileLinkInformation + || Iopb->Parameters.SetFileInformation.FileInformationClass == FileLinkInformationEx) { + // FILE_LINK_INFORMATION* FileInfo = (FILE_LINK_INFORMATION*)Iopb->Parameters.SetFileInformation.InfoBuffer; + + // For rename or link operations. If InfoBuffer->FileName contains a fully qualified file name, or if InfoBuffer->RootDirectory is non-NULL, + // this member is a file object pointer for the parent directory of the file that is the target of the operation. Otherwise it is NULL. + if (Iopb->Parameters.SetFileInformation.ParentOfTarget == NULL) { + + FLT_FILE_NAME_INFORMATION *pTargetFileNameInfo = NULL; + + if (FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &pTargetFileNameInfo) != STATUS_SUCCESS) + { + status = STATUS_ACCESS_DENIED; // if we can't get the name, just disallow the call + } + else + { + // if the file is to be created in the same directroy as the original file, we check if the original file is in a sandboxed location + if(!Box_IsBoxedPath(proc->box, file, &pTargetFileNameInfo->Name)) { + status = STATUS_ACCESS_DENIED; + } + } + + if (pTargetFileNameInfo != NULL) { + FltReleaseFileNameInformation(pTargetFileNameInfo); + } + } + else if(!Box_IsBoxedPath(proc->box, file, &Iopb->Parameters.SetFileInformation.ParentOfTarget->FileName)) { status = STATUS_ACCESS_DENIED; - goto finish; } } else { diff --git a/SandboxiePlus/MiscHelpers/Common/Common.h b/SandboxiePlus/MiscHelpers/Common/Common.h index 94319fca..21bc904a 100644 --- a/SandboxiePlus/MiscHelpers/Common/Common.h +++ b/SandboxiePlus/MiscHelpers/Common/Common.h @@ -20,7 +20,7 @@ MISCHELPERS_EXPORT StrPair Split2(const QString& String, QString Separator = "=" MISCHELPERS_EXPORT QStringList SplitStr(const QString& String, QString Separator); typedef MISCHELPERS_EXPORT QMap TArguments; -TArguments MISCHELPERS_EXPORT GetArguments(const QString& Arguments, QChar Separator = L';', QChar Assigner = L'=', QString* First = NULL, bool bLowerKeys = true, bool bReadEsc = false); +TArguments MISCHELPERS_EXPORT GetArguments(const QString& Arguments, QChar Separator = L';', QChar Assigner = L'=', QString* First = NULL, bool bLowerKeys = false, bool bReadEsc = false); MISCHELPERS_EXPORT QString UnEscape(QString Text); diff --git a/SandboxiePlus/SandMan/SandMan.cpp b/SandboxiePlus/SandMan/SandMan.cpp index a5eedeca..842a127a 100644 --- a/SandboxiePlus/SandMan/SandMan.cpp +++ b/SandboxiePlus/SandMan/SandMan.cpp @@ -2290,7 +2290,7 @@ void CSandMan::CheckForUpdates(bool bManual) Query.addQueryItem("system", "windows-" + QSysInfo::kernelVersion() + "-" + QSysInfo::currentCpuArchitecture()); Query.addQueryItem("language", QString::number(m_LanguageId)); - QString UpdateKey = GetArguments(g_Certificate, L'\n', L':').value("updatekey"); + QString UpdateKey = GetArguments(g_Certificate, L'\n', L':').value("UPDATEKEY"); if (UpdateKey.isEmpty()) UpdateKey = theAPI->GetGlobalSettings()->GetText("UpdateKey"); // theConf->GetString("Options/UpdateKey"); if (!UpdateKey.isEmpty()) @@ -2528,7 +2528,7 @@ void CSandMan::OnAbout() QString CertInfo; if (!g_Certificate.isEmpty()) { - CertInfo = tr("This copy of Sandboxie+ is certified for: %1").arg(GetArguments(g_Certificate, L'\n', L':').value("name")); + CertInfo = tr("This copy of Sandboxie+ is certified for: %1").arg(GetArguments(g_Certificate, L'\n', L':').value("NAME")); } else { CertInfo = tr("Sandboxie+ is free for personal and non-commercial use."); } @@ -2581,7 +2581,7 @@ void CSandMan::UpdateCert() { QString UpdateKey; // for now only patreons can update the cert automatically if(GetArguments(g_Certificate, L'\n', L':').value("type").indexOf("PATREON") == 0) - UpdateKey = GetArguments(g_Certificate, L'\n', L':').value("updatekey"); + UpdateKey = GetArguments(g_Certificate, L'\n', L':').value("UPDATEKEY"); if (UpdateKey.isEmpty()) { OpenUrl("https://sandboxie-plus.com/go.php?to=sbie-get-cert"); return; diff --git a/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp b/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp index 208dc302..93851e6f 100644 --- a/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp +++ b/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp @@ -531,12 +531,14 @@ void CSettingsWindow::SaveSettings() QString CertPath = theAPI->GetSbiePath() + "\\Certificate.dat"; if (!Certificate.isEmpty()) { + auto Args = GetArguments(Certificate, L'\n', L':'); + bool bLooksOk = true; - if (GetArguments(g_Certificate, L'\n', L':').value("NAME").isEmpty()) // mandatory + if (Args.value("NAME").isEmpty()) // mandatory bLooksOk = false; - //if (GetArguments(g_Certificate, L'\n', L':').value("UPDATEKEY").isEmpty()) + //if (Args.value("UPDATEKEY").isEmpty()) // bLooksOk = false; - if (GetArguments(g_Certificate, L'\n', L':').value("SIGNATURE").isEmpty()) // absolutely mandatory + if (Args.value("SIGNATURE").isEmpty()) // absolutely mandatory bLooksOk = false; if (bLooksOk) { diff --git a/SandboxiePlus/version.h b/SandboxiePlus/version.h index 0d030cad..f8f8f612 100644 --- a/SandboxiePlus/version.h +++ b/SandboxiePlus/version.h @@ -2,7 +2,7 @@ #define VERSION_MJR 1 #define VERSION_MIN 0 -#define VERSION_REV 12 +#define VERSION_REV 13 #define VERSION_UPD 0 #ifndef STR