mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 18:43:41 +00:00
[MOUNTMGR]
Fix CVE-2015-1769: - When opening remote databases, don't attempt to migrate w2k database to current format. - Also, when opening/creating the remote database, don't allow following symlinks anymore. In case a symlink would be detected, an error message will be printed. Commit dedicated to Alex :-). CORE-10216 #resolve #comment Fixed with r69295 svn path=/trunk/; revision=69295
This commit is contained in:
parent
25eb471cdf
commit
cd8e7fa978
1 changed files with 30 additions and 133 deletions
|
@ -32,7 +32,6 @@ PWSTR DatabasePath = L"\\Registry\\Machine\\System\\MountedDevices";
|
||||||
PWSTR OfflinePath = L"\\Registry\\Machine\\System\\MountedDevices\\Offline";
|
PWSTR OfflinePath = L"\\Registry\\Machine\\System\\MountedDevices\\Offline";
|
||||||
|
|
||||||
UNICODE_STRING RemoteDatabase = RTL_CONSTANT_STRING(L"\\System Volume Information\\MountPointManagerRemoteDatabase");
|
UNICODE_STRING RemoteDatabase = RTL_CONSTANT_STRING(L"\\System Volume Information\\MountPointManagerRemoteDatabase");
|
||||||
UNICODE_STRING RemoteDatabaseFile = RTL_CONSTANT_STRING(L"\\:$MountMgrRemoteDatabase");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
|
@ -1664,22 +1663,16 @@ ReconcileAllDatabasesWithMaster(IN PDEVICE_EXTENSION DeviceExtension)
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MigrateRemoteDatabaseWorker(IN PDEVICE_OBJECT DeviceObject,
|
CreateRemoteDatabaseWorker(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PVOID Context)
|
IN PVOID Context)
|
||||||
{
|
{
|
||||||
ULONG Length;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PVOID TmpBuffer;
|
HANDLE Database = 0;
|
||||||
CHAR Disposition;
|
UNICODE_STRING DatabaseName;
|
||||||
LARGE_INTEGER ByteOffset;
|
|
||||||
PMIGRATE_WORK_ITEM WorkItem;
|
PMIGRATE_WORK_ITEM WorkItem;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
HANDLE Migrate = 0, Database = 0;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
PDEVICE_INFORMATION DeviceInformation;
|
PDEVICE_INFORMATION DeviceInformation;
|
||||||
BOOLEAN PreviousMode, Complete = FALSE;
|
|
||||||
UNICODE_STRING DatabaseName, DatabaseFile;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes, MigrateAttributes;
|
|
||||||
#define TEMP_BUFFER_SIZE 0x200
|
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(DeviceObject);
|
UNREFERENCED_PARAMETER(DeviceObject);
|
||||||
|
|
||||||
|
@ -1690,15 +1683,8 @@ MigrateRemoteDatabaseWorker(IN PDEVICE_OBJECT DeviceObject,
|
||||||
/* Reconstruct appropriate string */
|
/* Reconstruct appropriate string */
|
||||||
DatabaseName.Length = DeviceInformation->DeviceName.Length + RemoteDatabase.Length;
|
DatabaseName.Length = DeviceInformation->DeviceName.Length + RemoteDatabase.Length;
|
||||||
DatabaseName.MaximumLength = DatabaseName.Length + sizeof(WCHAR);
|
DatabaseName.MaximumLength = DatabaseName.Length + sizeof(WCHAR);
|
||||||
|
|
||||||
DatabaseFile.Length = DeviceInformation->DeviceName.Length + RemoteDatabaseFile.Length;
|
|
||||||
DatabaseFile.MaximumLength = DatabaseFile.Length + sizeof(WCHAR);
|
|
||||||
|
|
||||||
DatabaseName.Buffer = AllocatePool(DatabaseName.MaximumLength);
|
DatabaseName.Buffer = AllocatePool(DatabaseName.MaximumLength);
|
||||||
DatabaseFile.Buffer = AllocatePool(DatabaseFile.MaximumLength);
|
if (DatabaseName.Buffer == NULL)
|
||||||
/* Allocate buffer that will be used to swap contents */
|
|
||||||
TmpBuffer = AllocatePool(TEMP_BUFFER_SIZE);
|
|
||||||
if (!DatabaseName.Buffer || !DatabaseFile.Buffer || !TmpBuffer)
|
|
||||||
{
|
{
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
|
@ -1715,13 +1701,9 @@ MigrateRemoteDatabaseWorker(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
/* Finish initating strings */
|
/* Finish initating strings */
|
||||||
RtlCopyMemory(DatabaseName.Buffer, DeviceInformation->DeviceName.Buffer, DeviceInformation->DeviceName.Length);
|
RtlCopyMemory(DatabaseName.Buffer, DeviceInformation->DeviceName.Buffer, DeviceInformation->DeviceName.Length);
|
||||||
RtlCopyMemory(DatabaseFile.Buffer, DeviceInformation->DeviceName.Buffer, DeviceInformation->DeviceName.Length);
|
|
||||||
RtlCopyMemory(DatabaseName.Buffer + (DeviceInformation->DeviceName.Length / sizeof(WCHAR)),
|
RtlCopyMemory(DatabaseName.Buffer + (DeviceInformation->DeviceName.Length / sizeof(WCHAR)),
|
||||||
RemoteDatabase.Buffer, RemoteDatabase.Length);
|
RemoteDatabase.Buffer, RemoteDatabase.Length);
|
||||||
RtlCopyMemory(DatabaseFile.Buffer + (DeviceInformation->DeviceName.Length / sizeof(WCHAR)),
|
|
||||||
RemoteDatabaseFile.Buffer, RemoteDatabaseFile.Length);
|
|
||||||
DatabaseName.Buffer[DatabaseName.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
DatabaseName.Buffer[DatabaseName.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
DatabaseFile.Buffer[DatabaseFile.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
|
||||||
|
|
||||||
/* Create database */
|
/* Create database */
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
@ -1730,7 +1712,7 @@ MigrateRemoteDatabaseWorker(IN PDEVICE_OBJECT DeviceObject,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
Status = ZwCreateFile(&Database,
|
Status = IoCreateFile(&Database,
|
||||||
SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES |
|
SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES |
|
||||||
FILE_READ_ATTRIBUTES | FILE_WRITE_PROPERTIES | FILE_READ_PROPERTIES |
|
FILE_READ_ATTRIBUTES | FILE_WRITE_PROPERTIES | FILE_READ_PROPERTIES |
|
||||||
FILE_APPEND_DATA | FILE_WRITE_DATA | FILE_READ_DATA,
|
FILE_APPEND_DATA | FILE_WRITE_DATA | FILE_READ_DATA,
|
||||||
|
@ -1742,123 +1724,32 @@ MigrateRemoteDatabaseWorker(IN PDEVICE_OBJECT DeviceObject,
|
||||||
FILE_CREATE,
|
FILE_CREATE,
|
||||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT,
|
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT,
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0,
|
||||||
|
CreateFileTypeNone,
|
||||||
|
NULL,
|
||||||
|
IO_STOP_ON_SYMLINK);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
if (Status == STATUS_STOPPED_ON_SYMLINK)
|
||||||
|
{
|
||||||
|
DPRINT1("Attempt to exploit CVE-2015-1769. See CORE-10216\n");
|
||||||
|
}
|
||||||
|
|
||||||
Database = 0;
|
Database = 0;
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeObjectAttributes(&MigrateAttributes,
|
|
||||||
&DatabaseFile,
|
|
||||||
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* Disable hard errors and open the database that will be copied */
|
|
||||||
PreviousMode = IoSetThreadHardErrorMode(FALSE);
|
|
||||||
Status = ZwCreateFile(&Migrate,
|
|
||||||
SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES |
|
|
||||||
FILE_READ_ATTRIBUTES | FILE_WRITE_PROPERTIES | FILE_READ_PROPERTIES |
|
|
||||||
FILE_APPEND_DATA | FILE_WRITE_DATA | FILE_READ_DATA,
|
|
||||||
&MigrateAttributes,
|
|
||||||
&IoStatusBlock,
|
|
||||||
NULL,
|
|
||||||
FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
|
|
||||||
0,
|
|
||||||
FILE_OPEN,
|
|
||||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT,
|
|
||||||
NULL,
|
|
||||||
0);
|
|
||||||
IoSetThreadHardErrorMode(PreviousMode);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Migrate = 0;
|
|
||||||
}
|
|
||||||
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
||||||
{
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
Complete = TRUE;
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status) || Complete)
|
|
||||||
{
|
|
||||||
goto Cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteOffset.QuadPart = 0LL;
|
|
||||||
PreviousMode = IoSetThreadHardErrorMode(FALSE);
|
|
||||||
/* Now, loop as long it's possible */
|
|
||||||
while (Status == STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Read data from existing database */
|
|
||||||
Status = ZwReadFile(Migrate,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&IoStatusBlock,
|
|
||||||
TmpBuffer,
|
|
||||||
TEMP_BUFFER_SIZE,
|
|
||||||
&ByteOffset,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* And write them into new database */
|
|
||||||
Length = (ULONG)IoStatusBlock.Information;
|
|
||||||
Status = ZwWriteFile(Database,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&IoStatusBlock,
|
|
||||||
TmpBuffer,
|
|
||||||
Length,
|
|
||||||
&ByteOffset,
|
|
||||||
NULL);
|
|
||||||
ByteOffset.QuadPart += Length;
|
|
||||||
}
|
|
||||||
IoSetThreadHardErrorMode(PreviousMode);
|
|
||||||
|
|
||||||
/* Delete old databse if it was well copied */
|
|
||||||
if (Status == STATUS_END_OF_FILE)
|
|
||||||
{
|
|
||||||
Disposition = 1;
|
|
||||||
Status = ZwSetInformationFile(Migrate,
|
|
||||||
&IoStatusBlock,
|
|
||||||
&Disposition,
|
|
||||||
sizeof(Disposition),
|
|
||||||
FileDispositionInformation);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Migration is over */
|
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
if (TmpBuffer)
|
|
||||||
{
|
|
||||||
FreePool(TmpBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DatabaseFile.Buffer)
|
|
||||||
{
|
|
||||||
FreePool(DatabaseFile.Buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DatabaseName.Buffer)
|
if (DatabaseName.Buffer)
|
||||||
{
|
{
|
||||||
FreePool(DatabaseName.Buffer);
|
FreePool(DatabaseName.Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Migrate)
|
|
||||||
{
|
|
||||||
ZwClose(Migrate);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DeviceInformation->Migrated = 1;
|
DeviceInformation->Migrated = 1;
|
||||||
}
|
}
|
||||||
else if (Database)
|
else if (Database != 0)
|
||||||
{
|
{
|
||||||
ZwClose(Database);
|
ZwClose(Database);
|
||||||
}
|
}
|
||||||
|
@ -1870,15 +1761,14 @@ Cleanup:
|
||||||
WorkItem->Database = Database;
|
WorkItem->Database = Database;
|
||||||
|
|
||||||
KeSetEvent(WorkItem->Event, 0, FALSE);
|
KeSetEvent(WorkItem->Event, 0, FALSE);
|
||||||
#undef TEMP_BUFFER_SIZE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MigrateRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation,
|
CreateRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation,
|
||||||
IN OUT PHANDLE Database)
|
IN OUT PHANDLE Database)
|
||||||
{
|
{
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -1907,7 +1797,7 @@ MigrateRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation,
|
||||||
|
|
||||||
/* And queue it */
|
/* And queue it */
|
||||||
IoQueueWorkItem(WorkItem->WorkItem,
|
IoQueueWorkItem(WorkItem->WorkItem,
|
||||||
MigrateRemoteDatabaseWorker,
|
CreateRemoteDatabaseWorker,
|
||||||
DelayedWorkQueue,
|
DelayedWorkQueue,
|
||||||
WorkItem);
|
WorkItem);
|
||||||
|
|
||||||
|
@ -1960,7 +1850,7 @@ OpenRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation,
|
||||||
/* Disable hard errors */
|
/* Disable hard errors */
|
||||||
PreviousMode = IoSetThreadHardErrorMode(FALSE);
|
PreviousMode = IoSetThreadHardErrorMode(FALSE);
|
||||||
|
|
||||||
Status = ZwCreateFile(&Database,
|
Status = IoCreateFile(&Database,
|
||||||
SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES |
|
SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES |
|
||||||
FILE_READ_ATTRIBUTES | FILE_WRITE_PROPERTIES | FILE_READ_PROPERTIES |
|
FILE_READ_ATTRIBUTES | FILE_WRITE_PROPERTIES | FILE_READ_PROPERTIES |
|
||||||
FILE_APPEND_DATA | FILE_WRITE_DATA | FILE_READ_DATA,
|
FILE_APPEND_DATA | FILE_WRITE_DATA | FILE_READ_DATA,
|
||||||
|
@ -1972,12 +1862,19 @@ OpenRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation,
|
||||||
(!MigrateDatabase || DeviceInformation->Migrated == 0) ? FILE_OPEN_IF : FILE_OPEN,
|
(!MigrateDatabase || DeviceInformation->Migrated == 0) ? FILE_OPEN_IF : FILE_OPEN,
|
||||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT,
|
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT,
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0,
|
||||||
|
CreateFileTypeNone,
|
||||||
|
NULL,
|
||||||
|
IO_STOP_ON_SYMLINK);
|
||||||
|
if (Status == STATUS_STOPPED_ON_SYMLINK)
|
||||||
|
{
|
||||||
|
DPRINT1("Attempt to exploit CVE-2015-1769. See CORE-10216\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* If base it to be migrated and was opened successfully, go ahead */
|
/* If base it to be migrated and was opened successfully, go ahead */
|
||||||
if (MigrateDatabase && NT_SUCCESS(Status))
|
if (MigrateDatabase && NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
MigrateRemoteDatabase(DeviceInformation, &Database);
|
CreateRemoteDatabase(DeviceInformation, &Database);
|
||||||
}
|
}
|
||||||
|
|
||||||
IoSetThreadHardErrorMode(PreviousMode);
|
IoSetThreadHardErrorMode(PreviousMode);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue