diff options
-rw-r--r-- | src/Common/Dlgcode.c | 10 | ||||
-rw-r--r-- | src/Common/Language.c | 3 | ||||
-rw-r--r-- | src/Common/Tests.c | 54 | ||||
-rw-r--r-- | src/Crypto/cpu.c | 4 | ||||
-rw-r--r-- | src/ExpandVolume/ExpandVolume.c | 6 | ||||
-rw-r--r-- | src/Format/InPlace.c | 2 | ||||
-rw-r--r-- | src/Format/Tcformat.c | 17 | ||||
-rw-r--r-- | src/Mount/Mount.c | 10 | ||||
-rw-r--r-- | src/Setup/Dir.c | 12 | ||||
-rw-r--r-- | src/Setup/Setup.c | 3 | ||||
-rw-r--r-- | src/SetupDLL/Dir.c | 12 |
11 files changed, 105 insertions, 28 deletions
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 9d5c0d06..7b3d2d45 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -579,93 +579,97 @@ BOOL LoadInt16 (const wchar_t *filePath, int *result, __int64 fileOffset) src = CreateFile (filePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (src == INVALID_HANDLE_VALUE) { free (buffer); return FALSE; } seekOffset.QuadPart = fileOffset; if (SetFilePointerEx (src, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0) goto fsif_end; if (ReadFile (src, buffer, bufSize, &bytesRead, NULL) == 0 || bytesRead != bufSize) goto fsif_end; retVal = TRUE; *result = mgetWord(bufferPtr); fsif_end: CloseHandle (src); free (buffer); return retVal; } // Returns NULL if there's any error. Although the buffer can contain binary data, it is always null-terminated. char *LoadFile (const wchar_t *fileName, DWORD *size) { char *buf; DWORD fileSize = INVALID_FILE_SIZE; HANDLE h = CreateFile (fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + *size = 0; if (h == INVALID_HANDLE_VALUE) return NULL; if ((fileSize = GetFileSize (h, NULL)) == INVALID_FILE_SIZE) { CloseHandle (h); return NULL; } - *size = fileSize; - buf = (char *) calloc (*size + 1, 1); + buf = (char *) calloc (fileSize + 1, 1); if (buf == NULL) { CloseHandle (h); return NULL; } - if (!ReadFile (h, buf, *size, size, NULL)) + if (!ReadFile (h, buf, fileSize, size, NULL)) { free (buf); buf = NULL; } + else + { + buf[*size] = 0; //make coverity happy eventhough buf is guaranteed to be null terminated because of fileSize+1 in calloc call + } CloseHandle (h); return buf; } // Returns NULL if there's any error. char *LoadFileBlock (const wchar_t *fileName, __int64 fileOffset, DWORD count) { char *buf; DWORD bytesRead = 0; LARGE_INTEGER seekOffset, seekOffsetNew; BOOL bStatus; HANDLE h = CreateFile (fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (h == INVALID_HANDLE_VALUE) return NULL; seekOffset.QuadPart = fileOffset; if (SetFilePointerEx (h, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0) { CloseHandle (h); return NULL; } buf = (char *) calloc (count, 1); if (buf == NULL) { CloseHandle (h); return NULL; } bStatus = ReadFile (h, buf, count, &bytesRead, NULL); diff --git a/src/Common/Language.c b/src/Common/Language.c index 844f4dad..278b7dd1 100644 --- a/src/Common/Language.c +++ b/src/Common/Language.c @@ -579,60 +579,61 @@ BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa if (lw == IDCANCEL) { EndDialog (hwndDlg, lw); return 1; } if (lw == IDC_GET_LANG_PACKS) { char tmpstr [256]; if (strlen (ActiveLangPackVersion) > 0 && strlen (GetPreferredLangId()) > 0) StringCbPrintfA (tmpstr, sizeof(tmpstr), "&langpackversion=%s&lang=%s", ActiveLangPackVersion, GetPreferredLangId()); else tmpstr[0] = 0; Applink ("localizations"); return 1; } return 0; } return 0; } char *GetPreferredLangId () { return PreferredLangId; } void SetPreferredLangId (char *langId) { - StringCbCopyA (PreferredLangId, sizeof(PreferredLangId), langId); + if (strlen(langId) < sizeof(PreferredLangId)) + StringCbCopyA (PreferredLangId, sizeof(PreferredLangId), langId); } char *GetActiveLangPackVersion () { return ActiveLangPackVersion; } wchar_t *GetString (const char *stringId) { WCHAR *str = (WCHAR *) GetDictionaryValue (stringId); if (str != NULL) return str; StringCbPrintfW (UnknownString, sizeof(UnknownString), UNKNOWN_STRING_ID L"%hs" UNKNOWN_STRING_ID, stringId); return UnknownString; } Font *GetFont (char *fontType) { return (Font *) GetDictionaryValue (fontType); } diff --git a/src/Common/Tests.c b/src/Common/Tests.c index 0fcd93ce..4f53d4ed 100644 --- a/src/Common/Tests.c +++ b/src/Common/Tests.c @@ -1487,114 +1487,138 @@ BOOL AutoTestAlgorithms (void) EnableHwEncryption (hwEncryptionEnabled); #if defined (_MSC_VER) && !defined (_UEFI) } __except (EXCEPTION_EXECUTE_HANDLER) { exceptionCatched = TRUE; } if (exceptionCatched) { /* unexepected exception raised. Disable all CPU extended feature and try again */ EnableHwEncryption (hwEncryptionEnabled); DisableCPUExtendedFeatures (); __try { result = DoAutoTestAlgorithms(); } __except (EXCEPTION_EXECUTE_HANDLER) { /* exception still occuring. Report failure. */ result = FALSE; } } #endif return result; } BOOL test_hmac_sha256 () { unsigned int i; int nTestsPerformed = 0; for (i = 0; i < sizeof (hmac_sha256_test_data) / sizeof(char *); i++) { char digest[1024]; /* large enough to hold digets and test vector inputs */ - memcpy (digest, hmac_sha256_test_data[i], strlen (hmac_sha256_test_data[i])); - hmac_sha256 (hmac_sha256_test_keys[i], (int) strlen (hmac_sha256_test_keys[i]), digest, (int) strlen (hmac_sha256_test_data[i])); - if (memcmp (digest, hmac_sha256_test_vectors[i], SHA256_DIGESTSIZE) != 0) - return FALSE; + size_t dataLen = strlen (hmac_sha256_test_data[i]); + if (dataLen <= sizeof(digest)) + { + memcpy (digest, hmac_sha256_test_data[i], dataLen); + hmac_sha256 (hmac_sha256_test_keys[i], (int) strlen (hmac_sha256_test_keys[i]), digest, (int) dataLen); + if (memcmp (digest, hmac_sha256_test_vectors[i], SHA256_DIGESTSIZE) != 0) + return FALSE; + else + nTestsPerformed++; + } else - nTestsPerformed++; + { + return FALSE; + } } return (nTestsPerformed == 6); } BOOL test_hmac_sha512 () { unsigned int i; int nTestsPerformed = 0; for (i = 0; i < sizeof (hmac_sha512_test_data) / sizeof(char *); i++) { char digest[1024]; /* large enough to hold digets and test vector inputs */ - memcpy (digest, hmac_sha512_test_data[i], (int) strlen (hmac_sha512_test_data[i])); - hmac_sha512 (hmac_sha512_test_keys[i], (int) strlen (hmac_sha512_test_keys[i]), digest, (int) strlen (hmac_sha512_test_data[i])); - if (memcmp (digest, hmac_sha512_test_vectors[i], SHA512_DIGESTSIZE) != 0) - return FALSE; + size_t dataLen = strlen (hmac_sha512_test_data[i]); + if (dataLen <= sizeof(digest)) + { + memcpy (digest, hmac_sha512_test_data[i], dataLen ); + hmac_sha512 (hmac_sha512_test_keys[i], (int) strlen (hmac_sha512_test_keys[i]), digest, (int) dataLen); + if (memcmp (digest, hmac_sha512_test_vectors[i], SHA512_DIGESTSIZE) != 0) + return FALSE; + else + nTestsPerformed++; + } else - nTestsPerformed++; + { + return FALSE; + } } return (nTestsPerformed == 6); } BOOL test_hmac_blake2s () { unsigned int i; int nTestsPerformed = 0; for (i = 0; i < sizeof (hmac_blake2s_test_data) / sizeof(char *); i++) { char digest[1024]; /* large enough to hold digets and test vector inputs */ - memcpy (digest, hmac_blake2s_test_data[i], strlen (hmac_blake2s_test_data[i])); - hmac_blake2s (hmac_blake2s_test_keys[i], (int) strlen (hmac_blake2s_test_keys[i]), digest, (int) strlen (hmac_blake2s_test_data[i])); - if (memcmp (digest, hmac_blake2s_test_vectors[i], BLAKE2S_DIGESTSIZE) != 0) - return FALSE; + size_t dataLen = strlen (hmac_blake2s_test_data[i]); + if (dataLen <= sizeof(digest)) + { + memcpy (digest, hmac_blake2s_test_data[i], dataLen); + hmac_blake2s (hmac_blake2s_test_keys[i], (int) strlen (hmac_blake2s_test_keys[i]), digest, (int) dataLen); + if (memcmp (digest, hmac_blake2s_test_vectors[i], BLAKE2S_DIGESTSIZE) != 0) + return FALSE; + else + nTestsPerformed++; + } else - nTestsPerformed++; + { + return FALSE; + } } return (nTestsPerformed == 6); } int __cdecl Blake2sHash (unsigned char* input, unsigned long inputLen, unsigned char* output) { blake2s(output, input, (size_t) inputLen); return BLAKE2S_DIGESTSIZE; } BOOL test_hmac_whirlpool () { unsigned char digest[1024]; /* large enough to hold digets and test vector inputs */ memcpy (digest, hmac_whirlpool_test_data, strlen (hmac_whirlpool_test_data)); hmac_whirlpool (hmac_whirlpool_test_key, 64, digest, (int) strlen (hmac_whirlpool_test_data)); if (memcmp (digest, hmac_whirlpool_test_vectors, WHIRLPOOL_DIGESTSIZE) != 0) return FALSE; return TRUE; } /* http://www.tc26.ru/methods/recommendation/%D0%A2%D0%9A26%D0%90%D0%9B%D0%93.pdf */ /* https://tools.ietf.org/html/draft-smyshlyaev-gost-usage-00 */ /* https://datatracker.ietf.org/doc/rfc7836/?include_text=1 */ static const unsigned char gost3411_2012_hmac_k1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; static const unsigned char gost3411_2012_hmac_m1[] = { 0x01, 0x26, 0xbd, 0xb8, 0x78, 0x00, 0xaf, 0x21, 0x43, 0x41, 0x45, 0x65, 0x63, 0x78, 0x01, 0x00 diff --git a/src/Crypto/cpu.c b/src/Crypto/cpu.c index 27d62e43..c3a769c8 100644 --- a/src/Crypto/cpu.c +++ b/src/Crypto/cpu.c @@ -248,139 +248,139 @@ static int TryAESNI () if (setjmp(s_jmpNoAESNI)) result = 0; else #endif { __m128i block, subkey, ciphered; // perform AES round. block = _mm_setr_epi32(0x11223344,0x55667788,0x99AABBCC,0xDDEEFF00); subkey = _mm_setr_epi32(0xA5A5A5A5,0xA5A5A5A5,0x5A5A5A5A,0x5A5A5A5A); ciphered = _mm_aesenc_si128(block, subkey); #ifdef _MSC_VER if (ciphered.m128i_u64[0] == LL(0x2f4654b9485061fa) && ciphered.m128i_u64[1] == LL(0xc8b51f1fe1256f99)) #else if (((uint64_t*)(&ciphered))[0] == LL(0x2f4654b9485061fa) && ((uint64_t*)(&ciphered))[1] == LL(0xc8b51f1fe1256f99)) #endif result = 1; } #ifdef _MSC_VER __except (EXCEPTION_EXECUTE_HANDLER) { // ignore error if AES-NI not supported } #else signal(SIGILL, oldHandler); #endif return result; } static int Detect_MS_HyperV_AES () { int hasAesNI = 0; // when Hyper-V is enabled on older versions of Windows Server (i.e. 2008 R2), the AES-NI capability // gets masked out for all applications, even running on the host. // We try to detect Hyper-V virtual CPU and perform a dummy AES-NI operation to check its real presence - uint32 cpuid[4]; + uint32 cpuid[4] = {0}; char HvProductName[13]; CpuId(0x40000000, cpuid); memcpy (HvProductName, &cpuid[1], 12); HvProductName[12] = 0; if (_stricmp(HvProductName, "Microsoft Hv") == 0) { #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) KFLOATING_SAVE floatingPointState; if (NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))) { #endif hasAesNI = TryAESNI (); #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) KeRestoreFloatingPointState (&floatingPointState); } #endif } return hasAesNI; } #endif void DetectX86Features() { uint32 cpuid[4] = {0}, cpuid1[4] = {0}, cpuid2[4] = {0}; if (!CpuId(0, cpuid)) return; if (!CpuId(1, cpuid1)) return; g_hasMMX = (cpuid1[3] & (1 << 23)) != 0; // cpuid1[2] & (1 << 27) is XSAVE/XRESTORE and signals OS support for SSE; use it to avoid probes. // See http://github.com/weidai11/cryptopp/issues/511 and http://stackoverflow.com/a/22521619/608639 if ((cpuid1[3] & (1 << 26)) != 0) g_hasSSE2 = (cpuid1[2] & (1 << 27)) || TrySSE2(); if (g_hasSSE2 && (cpuid1[2] & (1 << 28)) && (cpuid1[2] & (1 << 27)) && (cpuid1[2] & (1 << 26))) /* CPU has AVX and OS supports XSAVE/XRSTORE */ { uint64 xcrFeatureMask = xgetbv(); g_hasAVX = (xcrFeatureMask & 0x6) == 0x6; } g_hasAVX2 = g_hasAVX && (cpuid1[1] & (1 << 5)); g_hasBMI2 = g_hasSSE2 && (cpuid1[1] & (1 << 8)); g_hasSSE42 = g_hasSSE2 && (cpuid1[2] & (1 << 20)); g_hasSSE41 = g_hasSSE2 && (cpuid1[2] & (1 << 19)); g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9)); #ifndef CRYPTOPP_DISABLE_AESNI g_hasAESNI = g_hasSSE2 && (cpuid1[2] & (1<<25)); #endif g_hasCLMUL = g_hasSSE2 && (cpuid1[2] & (1<<1)); #if !defined (_UEFI) && ((defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE) // Hypervisor = bit 31 of ECX of CPUID leaf 0x1 // reference: http://artemonsecurity.com/vmde.pdf if (!g_hasAESNI && (cpuid1[2] & (1<<31))) { g_hasAESNI = Detect_MS_HyperV_AES (); } #endif if ((cpuid1[3] & (1 << 25)) != 0) g_hasISSE = 1; else { - uint32 cpuid2[4]; + uint32 cpuid2[4] = {0}; CpuId(0x080000000, cpuid2); if (cpuid2[0] >= 0x080000001) { CpuId(0x080000001, cpuid2); g_hasISSE = (cpuid2[3] & (1 << 22)) != 0; } } if (IsIntel(cpuid)) { g_isIntel = 1; g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf; g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1); g_hasRDRAND = (cpuid1[2] & (1 << 30)) != 0; if (cpuid[0] >= 7) { if (CpuId(7, cpuid2)) { g_hasRDSEED = (cpuid2[1] & (1 << 18)) != 0; g_hasAVX2 = (cpuid2[1] & (1 << 5)) != 0; g_hasBMI2 = (cpuid2[1] & (1 << 8)) != 0; } } } else if (IsAMD(cpuid) || IsHygon(cpuid)) { g_isAMD = 1; CpuId(0x80000005, cpuid); g_cacheLineSize = GETBYTE(cpuid[2], 0); g_hasRDRAND = (cpuid1[2] & (1 << 30)) != 0; if (cpuid[0] >= 7) { if (CpuId(7, cpuid2)) diff --git a/src/ExpandVolume/ExpandVolume.c b/src/ExpandVolume/ExpandVolume.c index 84f6cfe8..f62d93ae 100644 --- a/src/ExpandVolume/ExpandVolume.c +++ b/src/ExpandVolume/ExpandVolume.c @@ -410,70 +410,76 @@ int ExtendFileSystem (HWND hwndDlg , wchar_t *lpszVolume, Password *pVolumePassw nStatus = ERR_SUCCESS; goto error; } nStatus = ERR_OS_ERROR; goto error; } if (fs != EV_FS_TYPE_RAW && fs != EV_FS_TYPE_NTFS ) { // FsctlExtendVolume only supports NTFS and RAW -> return with no error nStatus = ERR_SUCCESS; goto error; } // Get volume GUID if (!GetVolumeNameForVolumeMountPoint(rootPath,szVolumeGUID,ARRAYSIZE(szVolumeGUID))) { nStatus = ERR_OS_ERROR; goto error; } else { // strip trailing backslash from volume GUID (otherwise it means root dir) size_t len = wcslen(szVolumeGUID); if (len>0) --len; if (szVolumeGUID[len]==L'\\') szVolumeGUID[len]=0; } // Get Sector Size if ( !GetNtfsNumberOfSectors(rootPath, NULL, &BytesPerSector) ) { nStatus = ERR_OS_ERROR; goto error; } + if ((BytesPerSector == 0) || (BytesPerSector > (DWORD)INT_MAX)) + { + nStatus = ERR_SECTOR_SIZE_INCOMPATIBLE; + goto error; + } + DebugAddProgressDlgStatus (hwndDlg, L"Extending file system ...\r\n"); // extend volume nStatus = FsctlExtendVolume(szVolumeGUID, newDataAreaSize/BytesPerSector ); error: dwError = GetLastError(); if (driveNo>=0) { DebugAddProgressDlgStatus (hwndDlg, L"Unmounting volume ...\r\n"); UnmountVolume (hwndDlg, driveNo, TRUE); } SetLastError (dwError); return nStatus; } /* ExpandVolume Sets the volume size in the volume header (and backup header) to a larger value, and resizes the filesystem within the volume (only NTFS supported) Parameters: hwndDlg : HWND [in] handle to progress dialog lpszVolume : char * [in] Pointer to a string that contains the path to the truecrypt volume pVolumePassword : Password * diff --git a/src/Format/InPlace.c b/src/Format/InPlace.c index 4a16fd4f..f6166dab 100644 --- a/src/Format/InPlace.c +++ b/src/Format/InPlace.c @@ -57,70 +57,72 @@ using namespace VeraCrypt; #endif #define TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE (2048 * BYTES_PER_KB) #define TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE (2 * TC_MAX_VOLUME_SECTOR_SIZE) #define TC_NTFS_CONCEAL_CONSTANT 0xFF #define TC_NONSYS_INPLACE_ENC_HEADER_UPDATE_INTERVAL (64 * BYTES_PER_MB) #define TC_NONSYS_INPLACE_ENC_MIN_VOL_SIZE (TC_TOTAL_VOLUME_HEADERS_SIZE + TC_MIN_NTFS_FS_SIZE * 2) // If the returned value is greater than 0, it is the desired volume size in NTFS sectors (not in bytes) // after shrinking has been performed. If there's any error, returns -1. static __int64 NewFileSysSizeAfterShrink (HANDLE dev, const wchar_t *devicePath, int64 *totalClusterCount, DWORD *bytesPerCluster, BOOL silent) { NTFS_VOLUME_DATA_BUFFER ntfsVolData; DWORD nBytesReturned; __int64 fileSysSize, desiredNbrSectors; // Filesystem size and sector size if (!DeviceIoControl (dev, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, (LPVOID) &ntfsVolData, sizeof (ntfsVolData), &nBytesReturned, NULL)) { if (!silent) handleWin32Error (MainDlg, SRC_POS); return -1; } if ( (ntfsVolData.NumberSectors.QuadPart <= 0) + || (ntfsVolData.BytesPerSector == 0) + || (ntfsVolData.BytesPerSector >= (DWORD) UINT_MAX) || (ntfsVolData.NumberSectors.QuadPart > (INT64_MAX / (__int64) ntfsVolData.BytesPerSector)) // overflow test ) { SetLastError (ERROR_INTERNAL_ERROR); if (!silent) handleWin32Error (MainDlg, SRC_POS); return -1; } fileSysSize = ntfsVolData.NumberSectors.QuadPart * ntfsVolData.BytesPerSector; desiredNbrSectors = (fileSysSize - TC_TOTAL_VOLUME_HEADERS_SIZE) / ntfsVolData.BytesPerSector; if (desiredNbrSectors <= 0) return -1; if (totalClusterCount) *totalClusterCount = ntfsVolData.TotalClusters.QuadPart; if (bytesPerCluster) *bytesPerCluster = ntfsVolData.BytesPerCluster; return desiredNbrSectors; } BOOL CheckRequirementsForNonSysInPlaceEnc (HWND hwndDlg, const wchar_t *devicePath, BOOL silent) { NTFS_VOLUME_DATA_BUFFER ntfsVolData; DWORD nBytesReturned; HANDLE dev; WCHAR szFileSysName [256]; WCHAR devPath [MAX_PATH]; WCHAR dosDev [TC_MAX_PATH] = {0}; WCHAR devName [MAX_PATH] = {0}; diff --git a/src/Format/Tcformat.c b/src/Format/Tcformat.c index 477306ea..efd95caf 100644 --- a/src/Format/Tcformat.c +++ b/src/Format/Tcformat.c @@ -9724,75 +9724,82 @@ int AnalyzeHiddenVolumeHost (HWND hwndDlg, int *driveNo, __int64 hiddenVolHostSi { handleWin32Error (hwndDlg, SRC_POS); goto efs_error; } result = ReadFile (hDevice, &readBuffer, TC_MAX_VOLUME_SECTOR_SIZE, &bytesReturned, NULL); if (result == 0) { handleWin32Error (hwndDlg, SRC_POS); MessageBoxW (hwndDlg, GetString ("CANT_ACCESS_OUTER_VOL"), lpszTitle, ICON_HAND); goto efs_error; } CloseHandle (hDevice); hDevice = INVALID_HANDLE_VALUE; // Determine file system type GetVolumeInformation(szRootPathName, NULL, 0, NULL, NULL, NULL, szFileSystemNameBuffer, ARRAYSIZE(szFileSystemNameBuffer)); // The Windows API sometimes fails to indentify the file system correctly so we're using "raw" analysis too. if (!wcsncmp (szFileSystemNameBuffer, L"FAT", 3) || (readBuffer[0x36] == 'F' && readBuffer[0x37] == 'A' && readBuffer[0x38] == 'T') || (readBuffer[0x52] == 'F' && readBuffer[0x53] == 'A' && readBuffer[0x54] == 'T')) { // FAT12/FAT16/FAT32 // Retrieve the cluster size *realClusterSize = ((int) readBuffer[0xb] + ((int) readBuffer[0xc] << 8)) * (int) readBuffer[0xd]; // Get the map of the clusters that are free and in use on the outer volume. // The map will be scanned to determine the size of the uninterrupted block of free // space (provided there is any) whose end is aligned with the end of the volume. // The value will then be used to determine the maximum possible size of the hidden volume. - - return ScanVolClusterBitmap (hwndDlg, - driveNo, - hiddenVolHostSize / *realClusterSize, - pnbrFreeClusters); + if (*realClusterSize > 0) + { + return ScanVolClusterBitmap (hwndDlg, + driveNo, + hiddenVolHostSize / *realClusterSize, + pnbrFreeClusters); + } + else + { + // should never happen + return -1; + } } else if (!wcsncmp (szFileSystemNameBuffer, L"NTFS", 4) || !_wcsnicmp (szFileSystemNameBuffer, L"exFAT", 5)) { // NTFS bool bIsNtfs = (0 == wcsncmp (szFileSystemNameBuffer, L"NTFS", 4)); if (bIsNtfs && bHiddenVolDirect && GetVolumeDataAreaSize (FALSE, hiddenVolHostSize) <= TC_MAX_FAT_SECTOR_COUNT * GetFormatSectorSize()) Info ("HIDDEN_VOL_HOST_NTFS", hwndDlg); if (!GetDiskFreeSpace(szRootPathName, &dwSectorsPerCluster, &dwBytesPerSector, &dwNumberOfFreeClusters, &dwTotalNumberOfClusters)) { handleWin32Error (hwndDlg, SRC_POS); Error ("CANT_GET_OUTER_VOL_INFO", hwndDlg); return -1; }; *realClusterSize = dwBytesPerSector * dwSectorsPerCluster; // Get the map of the clusters that are free and in use on the outer volume. // The map will be scanned to determine the size of the uninterrupted block of free // space (provided there is any) whose end is aligned with the end of the volume. // The value will then be used to determine the maximum possible size of the hidden volume. return ScanVolClusterBitmap (hwndDlg, driveNo, hiddenVolHostSize / *realClusterSize, pnbrFreeClusters); } else { // Unsupported file system diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index a0370861..a5798afc 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -6551,88 +6551,96 @@ static void VerifyRescueDisk (HWND hwndDlg, bool checkImageFile) { WaitCursor(); if (!BootEncObj->VerifyRescueDisk ()) Error (bSystemIsGPT? "RESCUE_DISK_EFI_NON_WIZARD_CHECK_FAILED" : "RESCUE_DISK_NON_WIZARD_CHECK_FAILED", hwndDlg); else Info ("RESCUE_DISK_NON_WIZARD_CHECK_PASSED", hwndDlg); } } catch (Exception &e) { e.Show (MainDlg); Error (bSystemIsGPT? "RESCUE_DISK_EFI_NON_WIZARD_CHECK_FAILED" : "RESCUE_DISK_NON_WIZARD_CHECK_FAILED", hwndDlg); } CloseSysEncMutex (); NormalCursor (); } else Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); } static void ShowSystemEncryptionStatus (HWND hwndDlg) { try { BootEncStatus = BootEncObj->GetStatus(); } catch (Exception &e) { e.Show (MainDlg); } if (GetAsyncKeyState (VK_SHIFT) < 0 && GetAsyncKeyState (VK_CONTROL) < 0) { // Ctrl+Shift held (for debugging purposes) + int64 encryptedRatio = 0; + if (BootEncStatus.DriveEncrypted + && (BootEncStatus.ConfiguredEncryptedAreaStart >= 0) + && (BootEncStatus.ConfiguredEncryptedAreaEnd >= BootEncStatus.ConfiguredEncryptedAreaStart) + ) + { + encryptedRatio = (BootEncStatus.EncryptedAreaEnd + 1 - BootEncStatus.EncryptedAreaStart) * 100I64 / (BootEncStatus.ConfiguredEncryptedAreaEnd + 1 - BootEncStatus.ConfiguredEncryptedAreaStart); + } DebugMsgBox ("Debugging information for system encryption:\n\nDeviceFilterActive: %d\nBootLoaderVersion: %x\nSetupInProgress: %d\nSetupMode: %d\nVolumeHeaderPresent: %d\nDriveMounted: %d\nDriveEncrypted: %d\n" "HiddenSystem: %d\nHiddenSystemPartitionStart: %I64d\n" "ConfiguredEncryptedAreaStart: %I64d\nConfiguredEncryptedAreaEnd: %I64d\nEncryptedAreaStart: %I64d\nEncryptedAreaEnd: %I64d\nEncrypted: %I64d%%", BootEncStatus.DeviceFilterActive, BootEncStatus.BootLoaderVersion, BootEncStatus.SetupInProgress, BootEncStatus.SetupMode, BootEncStatus.VolumeHeaderPresent, BootEncStatus.DriveMounted, BootEncStatus.DriveEncrypted, BootEncStatus.HiddenSystem ? 1 : 0, BootEncStatus.HiddenSystemPartitionStart, BootEncStatus.ConfiguredEncryptedAreaStart, BootEncStatus.ConfiguredEncryptedAreaEnd, BootEncStatus.EncryptedAreaStart, BootEncStatus.EncryptedAreaEnd, - !BootEncStatus.DriveEncrypted ? 0 : (BootEncStatus.EncryptedAreaEnd + 1 - BootEncStatus.EncryptedAreaStart) * 100I64 / (BootEncStatus.ConfiguredEncryptedAreaEnd + 1 - BootEncStatus.ConfiguredEncryptedAreaStart)); + encryptedRatio); } if (!BootEncStatus.DriveEncrypted && !BootEncStatus.DriveMounted) { Info ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); return; } DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_VOLUME_PROPERTIES), hwndDlg, (DLGPROC) VolumePropertiesDlgProc, (LPARAM) TRUE); } static void ResumeInterruptedNonSysInplaceEncProcess (BOOL bDecrypt) { // IMPORTANT: This function must not check any config files! Otherwise, if a config file was lost or corrupt, // the user would not be able resume encryption and the data on the volume would be inaccessible. LaunchVolCreationWizard (MainDlg, bDecrypt? L"/resumeinplacedec" : L"/zinplace", FALSE); } BOOL SelectContainer (HWND hwndDlg) { if (BrowseFiles (hwndDlg, "OPEN_VOL_TITLE", szFileName, bHistory, FALSE, NULL) == FALSE) return FALSE; AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); EnableDisableButtons (hwndDlg); SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); return TRUE; } BOOL SelectPartition (HWND hwndDlg) { diff --git a/src/Setup/Dir.c b/src/Setup/Dir.c index 2d4feecd..3275567f 100644 --- a/src/Setup/Dir.c +++ b/src/Setup/Dir.c @@ -1,103 +1,115 @@ /* Legal Notice: Some portions of the source code contained in this file were derived from the source code of TrueCrypt 7.1a, which is Copyright (c) 2003-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0, also from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses' Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #include "Tcdefs.h" #include <sys/types.h> #include <sys/stat.h> #include <direct.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <Strsafe.h> #include "Dir.h" /* create full directory tree. returns 0 for success, -1 if failure */ int mkfulldir (wchar_t *oriPath, BOOL bCheckonly) { struct _stat st; wchar_t *uniq_file; wchar_t path [TC_MAX_PATH]; + if (wcslen(oriPath) >= TC_MAX_PATH) + { + // directory name will be truncated so return failure to avoid unexepected behavior + return -1; + } + StringCbCopyW (path, TC_MAX_PATH, oriPath); if (wcslen (path) == 3 && path[1] == L':') goto is_root; /* keep final slash in root if present */ /* strip final forward or backslash if we have one! */ uniq_file = wcsrchr (path, L'\\'); if (uniq_file && uniq_file[1] == L'\0') uniq_file[0] = L'\0'; else { uniq_file = wcsrchr (path, L'/'); if (uniq_file && uniq_file[1] == L'\0') uniq_file[0] = L'\0'; } is_root: if (bCheckonly) return _wstat (path, &st); if (_wstat (path, &st)) return mkfulldir_internal (path); else return 0; } int mkfulldir_internal (wchar_t *path) { wchar_t *token; struct _stat st; static wchar_t tokpath[_MAX_PATH]; static wchar_t trail[_MAX_PATH]; + if (wcslen(path) >= _MAX_PATH) + { + // directory name will be truncated so return failure to avoid unexepected behavior + return -1; + } + StringCbCopyW (tokpath, _MAX_PATH, path); trail[0] = L'\0'; token = wcstok (tokpath, L"\\/"); if (tokpath[0] == L'\\' && tokpath[1] == L'\\') { /* unc */ trail[0] = tokpath[0]; trail[1] = tokpath[1]; trail[2] = L'\0'; if (token) { StringCbCatW (trail, _MAX_PATH, token); StringCbCatW (trail, _MAX_PATH, L"\\"); token = wcstok (NULL, L"\\/"); if (token) { /* get share name */ StringCbCatW (trail, _MAX_PATH, token); StringCbCatW (trail, _MAX_PATH, L"\\"); } token = wcstok (NULL, L"\\/"); } } if (tokpath[1] == L':') { /* drive letter */ StringCbCatW (trail, _MAX_PATH, tokpath); StringCbCatW (trail, _MAX_PATH, L"\\"); token = wcstok (NULL, L"\\/"); } while (token != NULL) { int x; StringCbCatW (trail, _MAX_PATH, token); diff --git a/src/Setup/Setup.c b/src/Setup/Setup.c index 9433bd40..43c951f5 100644 --- a/src/Setup/Setup.c +++ b/src/Setup/Setup.c @@ -787,71 +787,72 @@ BOOL DoFilesInstall (HWND hwndDlg, wchar_t *szDestDir) GetModuleFileName (NULL, szTmp, ARRAYSIZE (szTmp)); if (!SelfExtractInMemory (szTmp, FALSE)) return FALSE; } x = wcslen (szDestDir); if (x < 2) return FALSE; if (szDestDir[x - 1] != L'\\') StringCbCatW (szDestDir, MAX_PATH, L"\\"); for (i = 0; i < sizeof (szFiles) / sizeof (szFiles[0]); i++) { BOOL bResult, driver64 = FALSE, zipFile = FALSE; wchar_t szDir[TC_MAX_PATH]; if (wcsstr (szFiles[i], L"VeraCrypt Setup") != 0) { if (bUninstall) continue; // Prevent 'access denied' error if (bRepairMode) continue; // Destination = target } if ((*szFiles[i] == L'A') || (*szFiles[i] == L'X')) StringCbCopyW (szDir, sizeof(szDir), szDestDir); else if (*szFiles[i] == L'D') { if (Is64BitOs ()) driver64 = TRUE; - GetSystemDirectory (szDir, ARRAYSIZE (szDir)); + if (!GetSystemDirectory (szDir, ARRAYSIZE (szDir))) + StringCbCopyW(szDir, sizeof(szDir), L"C:\\Windows\\System32"); x = wcslen (szDir); if (szDir[x - 1] != L'\\') StringCbCatW (szDir, sizeof(szDir), L"\\"); StringCbCatW (szDir, sizeof(szDir), L"Drivers\\"); } else if (*szFiles[i] == L'W') GetWindowsDirectory (szDir, ARRAYSIZE (szDir)); if (*szFiles[i] == L'I') continue; if (*szFiles[i] == L'X') zipFile = TRUE; StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szDir, szFiles[i] + 1); if (zipFile) { // build folder name by removing .zip extension wchar_t* ptr = wcsrchr (szTmp, L'.'); if (ptr) *ptr = 0; } if (bUninstall == FALSE) CopyMessage (hwndDlg, szTmp); else RemoveMessage (hwndDlg, szTmp); if (bUninstall == FALSE) { SetCurrentDirectory (SetupFilesDir); if (wcsstr (szFiles[i], L"VeraCrypt Setup") != 0) diff --git a/src/SetupDLL/Dir.c b/src/SetupDLL/Dir.c index 2d4feecd..3275567f 100644 --- a/src/SetupDLL/Dir.c +++ b/src/SetupDLL/Dir.c @@ -1,103 +1,115 @@ /* Legal Notice: Some portions of the source code contained in this file were derived from the source code of TrueCrypt 7.1a, which is Copyright (c) 2003-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0, also from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses' Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #include "Tcdefs.h" #include <sys/types.h> #include <sys/stat.h> #include <direct.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <Strsafe.h> #include "Dir.h" /* create full directory tree. returns 0 for success, -1 if failure */ int mkfulldir (wchar_t *oriPath, BOOL bCheckonly) { struct _stat st; wchar_t *uniq_file; wchar_t path [TC_MAX_PATH]; + if (wcslen(oriPath) >= TC_MAX_PATH) + { + // directory name will be truncated so return failure to avoid unexepected behavior + return -1; + } + StringCbCopyW (path, TC_MAX_PATH, oriPath); if (wcslen (path) == 3 && path[1] == L':') goto is_root; /* keep final slash in root if present */ /* strip final forward or backslash if we have one! */ uniq_file = wcsrchr (path, L'\\'); if (uniq_file && uniq_file[1] == L'\0') uniq_file[0] = L'\0'; else { uniq_file = wcsrchr (path, L'/'); if (uniq_file && uniq_file[1] == L'\0') uniq_file[0] = L'\0'; } is_root: if (bCheckonly) return _wstat (path, &st); if (_wstat (path, &st)) return mkfulldir_internal (path); else return 0; } int mkfulldir_internal (wchar_t *path) { wchar_t *token; struct _stat st; static wchar_t tokpath[_MAX_PATH]; static wchar_t trail[_MAX_PATH]; + if (wcslen(path) >= _MAX_PATH) + { + // directory name will be truncated so return failure to avoid unexepected behavior + return -1; + } + StringCbCopyW (tokpath, _MAX_PATH, path); trail[0] = L'\0'; token = wcstok (tokpath, L"\\/"); if (tokpath[0] == L'\\' && tokpath[1] == L'\\') { /* unc */ trail[0] = tokpath[0]; trail[1] = tokpath[1]; trail[2] = L'\0'; if (token) { StringCbCatW (trail, _MAX_PATH, token); StringCbCatW (trail, _MAX_PATH, L"\\"); token = wcstok (NULL, L"\\/"); if (token) { /* get share name */ StringCbCatW (trail, _MAX_PATH, token); StringCbCatW (trail, _MAX_PATH, L"\\"); } token = wcstok (NULL, L"\\/"); } } if (tokpath[1] == L':') { /* drive letter */ StringCbCatW (trail, _MAX_PATH, tokpath); StringCbCatW (trail, _MAX_PATH, L"\\"); token = wcstok (NULL, L"\\/"); } while (token != NULL) { int x; StringCbCatW (trail, _MAX_PATH, token); |