mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-24 20:13:33 +01:00
Windows Driver: Modify fix for CVE-2015-7358 to solve side effects on Windows mount manager while still making it hard to abuse drive letter handling.
This commit is contained in:
parent
ea451c7241
commit
c94f8c9b63
@ -322,7 +322,8 @@ typedef struct
|
|||||||
|
|
||||||
#define NT_MOUNT_PREFIX DRIVER_STR("\\Device\\VeraCryptVolume")
|
#define NT_MOUNT_PREFIX DRIVER_STR("\\Device\\VeraCryptVolume")
|
||||||
#define NT_ROOT_PREFIX DRIVER_STR("\\Device\\VeraCrypt")
|
#define NT_ROOT_PREFIX DRIVER_STR("\\Device\\VeraCrypt")
|
||||||
#define DOS_MOUNT_PREFIX DRIVER_STR("\\GLOBAL??\\") // Explicitely use Global MS-DOS device names to avoid security issues
|
#define DOS_MOUNT_PREFIX_DEFAULT DRIVER_STR("\\DosDevices\\")
|
||||||
|
#define DOS_MOUNT_PREFIX_GLOBAL DRIVER_STR("\\GLOBAL??\\") // Use Global MS-DOS device names for sanity checks on drive letters
|
||||||
#define DOS_ROOT_PREFIX DRIVER_STR("\\DosDevices\\VeraCrypt")
|
#define DOS_ROOT_PREFIX DRIVER_STR("\\DosDevices\\VeraCrypt")
|
||||||
#define WIN32_ROOT_PREFIX DRIVER_STR("\\\\.\\VeraCrypt")
|
#define WIN32_ROOT_PREFIX DRIVER_STR("\\\\.\\VeraCrypt")
|
||||||
|
|
||||||
|
@ -586,7 +586,7 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TCGetDosNameFromNumber (ntName, sizeof(ntName),Extension->nDosDriveNo);
|
TCGetDosNameFromNumber (ntName, sizeof(ntName),Extension->nDosDriveNo, DeviceNamespaceDefault);
|
||||||
RtlInitUnicodeString (&ntUnicodeString, ntName);
|
RtlInitUnicodeString (&ntUnicodeString, ntName);
|
||||||
|
|
||||||
outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length;
|
outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length;
|
||||||
@ -1965,14 +1965,23 @@ void TCGetNTNameFromNumber (LPWSTR ntname, int cbNtName, int nDriveNo)
|
|||||||
RtlStringCbCatW (ntname, cbNtName, tmp);
|
RtlStringCbCatW (ntname, cbNtName, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCGetDosNameFromNumber (LPWSTR dosname,int cbDosName, int nDriveNo)
|
void TCGetDosNameFromNumber (LPWSTR dosname,int cbDosName, int nDriveNo, DeviceNamespaceType namespaceType)
|
||||||
{
|
{
|
||||||
WCHAR tmp[3] =
|
WCHAR tmp[3] =
|
||||||
{0, ':', 0};
|
{0, ':', 0};
|
||||||
int j = nDriveNo + (WCHAR) 'A';
|
int j = nDriveNo + (WCHAR) 'A';
|
||||||
|
|
||||||
tmp[0] = (short) j;
|
tmp[0] = (short) j;
|
||||||
RtlStringCbCopyW (dosname, cbDosName, (LPWSTR) DOS_MOUNT_PREFIX);
|
|
||||||
|
if (DeviceNamespaceGlobal == namespaceType)
|
||||||
|
{
|
||||||
|
RtlStringCbCopyW (dosname, cbDosName, (LPWSTR) DOS_MOUNT_PREFIX_GLOBAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlStringCbCopyW (dosname, cbDosName, (LPWSTR) DOS_MOUNT_PREFIX_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
RtlStringCbCatW (dosname, cbDosName, tmp);
|
RtlStringCbCatW (dosname, cbDosName, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2538,7 +2547,7 @@ NTSTATUS CreateDriveLink (int nDosDriveNo)
|
|||||||
NTSTATUS ntStatus;
|
NTSTATUS ntStatus;
|
||||||
|
|
||||||
TCGetNTNameFromNumber (dev, sizeof(dev),nDosDriveNo);
|
TCGetNTNameFromNumber (dev, sizeof(dev),nDosDriveNo);
|
||||||
TCGetDosNameFromNumber (link, sizeof(link),nDosDriveNo);
|
TCGetDosNameFromNumber (link, sizeof(link),nDosDriveNo, DeviceNamespaceDefault);
|
||||||
|
|
||||||
RtlInitUnicodeString (&deviceName, dev);
|
RtlInitUnicodeString (&deviceName, dev);
|
||||||
RtlInitUnicodeString (&symLink, link);
|
RtlInitUnicodeString (&symLink, link);
|
||||||
@ -2555,7 +2564,7 @@ NTSTATUS RemoveDriveLink (int nDosDriveNo)
|
|||||||
UNICODE_STRING symLink;
|
UNICODE_STRING symLink;
|
||||||
NTSTATUS ntStatus;
|
NTSTATUS ntStatus;
|
||||||
|
|
||||||
TCGetDosNameFromNumber (link, sizeof(link),nDosDriveNo);
|
TCGetDosNameFromNumber (link, sizeof(link),nDosDriveNo, DeviceNamespaceDefault);
|
||||||
RtlInitUnicodeString (&symLink, link);
|
RtlInitUnicodeString (&symLink, link);
|
||||||
|
|
||||||
ntStatus = IoDeleteSymbolicLink (&symLink);
|
ntStatus = IoDeleteSymbolicLink (&symLink);
|
||||||
@ -2580,7 +2589,7 @@ NTSTATUS MountManagerMount (MOUNT_STRUCT *mount)
|
|||||||
in, (ULONG) (sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2), 0, 0);
|
in, (ULONG) (sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2), 0, 0);
|
||||||
|
|
||||||
memset (buf, 0, sizeof buf);
|
memset (buf, 0, sizeof buf);
|
||||||
TCGetDosNameFromNumber ((PWSTR) &point[1], sizeof(buf) - sizeof(MOUNTMGR_CREATE_POINT_INPUT),mount->nDosDriveNo);
|
TCGetDosNameFromNumber ((PWSTR) &point[1], sizeof(buf) - sizeof(MOUNTMGR_CREATE_POINT_INPUT),mount->nDosDriveNo, DeviceNamespaceDefault);
|
||||||
|
|
||||||
point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
|
point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
|
||||||
point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2;
|
point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2;
|
||||||
@ -2604,7 +2613,7 @@ NTSTATUS MountManagerUnmount (int nDosDriveNo)
|
|||||||
|
|
||||||
memset (buf, 0, sizeof buf);
|
memset (buf, 0, sizeof buf);
|
||||||
|
|
||||||
TCGetDosNameFromNumber ((PWSTR) &in[1], sizeof(buf) - sizeof(MOUNTMGR_MOUNT_POINT),nDosDriveNo);
|
TCGetDosNameFromNumber ((PWSTR) &in[1], sizeof(buf) - sizeof(MOUNTMGR_MOUNT_POINT),nDosDriveNo, DeviceNamespaceDefault);
|
||||||
|
|
||||||
// Only symbolic link can be deleted with IOCTL_MOUNTMGR_DELETE_POINTS. If any other entry is specified, the mount manager will ignore subsequent IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION for the same volume ID.
|
// Only symbolic link can be deleted with IOCTL_MOUNTMGR_DELETE_POINTS. If any other entry is specified, the mount manager will ignore subsequent IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION for the same volume ID.
|
||||||
in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT);
|
in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT);
|
||||||
@ -2625,7 +2634,10 @@ NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount)
|
|||||||
NTSTATUS ntStatus;
|
NTSTATUS ntStatus;
|
||||||
|
|
||||||
// Make sure the user is asking for a reasonable nDosDriveNo
|
// Make sure the user is asking for a reasonable nDosDriveNo
|
||||||
if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25 && IsDriveLetterAvailable (mount->nDosDriveNo))
|
if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25
|
||||||
|
&& IsDriveLetterAvailable (mount->nDosDriveNo, DeviceNamespaceDefault) // drive letter must not exist both locally and globally
|
||||||
|
&& IsDriveLetterAvailable (mount->nDosDriveNo, DeviceNamespaceGlobal)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Dump ("Mount request looks valid\n");
|
Dump ("Mount request looks valid\n");
|
||||||
}
|
}
|
||||||
@ -2716,6 +2728,16 @@ NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount)
|
|||||||
|
|
||||||
NewExtension->UniqueVolumeId = LastUniqueVolumeId++;
|
NewExtension->UniqueVolumeId = LastUniqueVolumeId++;
|
||||||
|
|
||||||
|
// check again that the drive letter is available globally and locally
|
||||||
|
if ( !IsDriveLetterAvailable (mount->nDosDriveNo, DeviceNamespaceDefault)
|
||||||
|
|| !IsDriveLetterAvailable (mount->nDosDriveNo, DeviceNamespaceGlobal)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
TCDeleteDeviceObject (NewDeviceObject, NewExtension);
|
||||||
|
mount->nReturnCode = ERR_DRIVE_NOT_FOUND;
|
||||||
|
return ERR_DRIVE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
if (mount->bMountManager)
|
if (mount->bMountManager)
|
||||||
MountManagerMount (mount);
|
MountManagerMount (mount);
|
||||||
|
|
||||||
@ -3049,8 +3071,7 @@ BOOL UserCanAccessDriveDevice ()
|
|||||||
return IsAccessibleByUser (&name, FALSE);
|
return IsAccessibleByUser (&name, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL IsDriveLetterAvailable (int nDosDriveNo, DeviceNamespaceType namespaceType)
|
||||||
BOOL IsDriveLetterAvailable (int nDosDriveNo)
|
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES objectAttributes;
|
OBJECT_ATTRIBUTES objectAttributes;
|
||||||
UNICODE_STRING objectName;
|
UNICODE_STRING objectName;
|
||||||
@ -3058,7 +3079,7 @@ BOOL IsDriveLetterAvailable (int nDosDriveNo)
|
|||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
NTSTATUS ntStatus;
|
NTSTATUS ntStatus;
|
||||||
|
|
||||||
TCGetDosNameFromNumber (link, sizeof(link),nDosDriveNo);
|
TCGetDosNameFromNumber (link, sizeof(link),nDosDriveNo, namespaceType);
|
||||||
RtlInitUnicodeString (&objectName, link);
|
RtlInitUnicodeString (&objectName, link);
|
||||||
InitializeObjectAttributes (&objectAttributes, &objectName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
InitializeObjectAttributes (&objectAttributes, &objectName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
|
|
||||||
|
@ -101,6 +101,11 @@ typedef enum
|
|||||||
ValidateInputOutput
|
ValidateInputOutput
|
||||||
} ValidateIOBufferSizeType;
|
} ValidateIOBufferSizeType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DeviceNamespaceDefault,
|
||||||
|
DeviceNamespaceGlobal,
|
||||||
|
} DeviceNamespaceType;
|
||||||
|
|
||||||
extern PDRIVER_OBJECT TCDriverObject;
|
extern PDRIVER_OBJECT TCDriverObject;
|
||||||
extern PDEVICE_OBJECT RootDeviceObject;
|
extern PDEVICE_OBJECT RootDeviceObject;
|
||||||
@ -133,7 +138,7 @@ void TCStopVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension);
|
|||||||
VOID VolumeThreadProc (PVOID Context);
|
VOID VolumeThreadProc (PVOID Context);
|
||||||
void TCSleep (int milliSeconds);
|
void TCSleep (int milliSeconds);
|
||||||
void TCGetNTNameFromNumber (LPWSTR ntname, int cbNtName, int nDriveNo);
|
void TCGetNTNameFromNumber (LPWSTR ntname, int cbNtName, int nDriveNo);
|
||||||
void TCGetDosNameFromNumber (LPWSTR dosname, int cbDosName, int nDriveNo);
|
void TCGetDosNameFromNumber (LPWSTR dosname, int cbDosName, int nDriveNo, DeviceNamespaceType namespaceType);
|
||||||
LPWSTR TCTranslateCode (ULONG ulCode);
|
LPWSTR TCTranslateCode (ULONG ulCode);
|
||||||
void TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension);
|
void TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension);
|
||||||
VOID TCUnloadDriver (PDRIVER_OBJECT DriverObject);
|
VOID TCUnloadDriver (PDRIVER_OBJECT DriverObject);
|
||||||
@ -161,7 +166,7 @@ BOOL UserCanAccessDriveDevice ();
|
|||||||
size_t GetCpuCount ();
|
size_t GetCpuCount ();
|
||||||
void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes);
|
void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes);
|
||||||
void *AllocateMemoryWithTimeout (size_t size, int retryDelay, int timeout);
|
void *AllocateMemoryWithTimeout (size_t size, int retryDelay, int timeout);
|
||||||
BOOL IsDriveLetterAvailable (int nDosDriveNo);
|
BOOL IsDriveLetterAvailable (int nDosDriveNo, DeviceNamespaceType namespaceType);
|
||||||
NTSTATUS TCReadRegistryKey (PUNICODE_STRING keyPath, wchar_t *keyValueName, PKEY_VALUE_PARTIAL_INFORMATION *keyData);
|
NTSTATUS TCReadRegistryKey (PUNICODE_STRING keyPath, wchar_t *keyValueName, PKEY_VALUE_PARTIAL_INFORMATION *keyData);
|
||||||
NTSTATUS TCWriteRegistryKey (PUNICODE_STRING keyPath, wchar_t *keyValueName, ULONG keyValueType, void *valueData, ULONG valueSize);
|
NTSTATUS TCWriteRegistryKey (PUNICODE_STRING keyPath, wchar_t *keyValueName, ULONG keyValueType, void *valueData, ULONG valueSize);
|
||||||
BOOL IsVolumeClassFilterRegistered ();
|
BOOL IsVolumeClassFilterRegistered ();
|
||||||
|
Loading…
Reference in New Issue
Block a user