Refering to CVE-2015-1769/MS15-085? On 14/09/2015 05:24, Alex Ionescu wrote: > Lol, make sure not to implement the huge vulnerability Microsoft patched > two months ago (win2k->xp-style database migration). > > Best regards, > Alex Ionescu > > On Sun, Sep 13, 2015 at 6:52 PM, <pschweit...@svn.reactos.org> wrote: > >> Author: pschweitzer >> Date: Sun Sep 13 22:52:07 2015 >> New Revision: 69221 >> >> URL: http://svn.reactos.org/svn/reactos?rev=69221&view=rev >> Log: >> [MOUNTMGR] >> Implement the IOCTL IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED: >> - Implement WriteRemoteDatabaseEntry() >> - Implement MountMgrVolumeMountPointCreated() >> >> Modified: >> trunk/reactos/drivers/filters/mountmgr/database.c >> trunk/reactos/drivers/filters/mountmgr/device.c >> trunk/reactos/drivers/filters/mountmgr/mntmgr.h >> trunk/reactos/drivers/filters/mountmgr/mountmgr.c >> >> Modified: trunk/reactos/drivers/filters/mountmgr/database.c >> URL: >> http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filters/mountmgr/database.c?rev=69221&r1=69220&r2=69221&view=diff >> >> ============================================================================== >> --- trunk/reactos/drivers/filters/mountmgr/database.c [iso-8859-1] >> (original) >> +++ trunk/reactos/drivers/filters/mountmgr/database.c [iso-8859-1] Sun >> Sep 13 22:52:07 2015 >> @@ -192,6 +192,39 @@ >> } >> >> return Entry; >> +} >> + >> +/* >> + * @implemented >> + */ >> +NTSTATUS >> +WriteRemoteDatabaseEntry(IN HANDLE Database, >> + IN LONG Offset, >> + IN PDATABASE_ENTRY Entry) >> +{ >> + NTSTATUS Status; >> + LARGE_INTEGER ByteOffset; >> + IO_STATUS_BLOCK IoStatusBlock; >> + >> + ByteOffset.QuadPart = Offset; >> + Status = ZwWriteFile(Database, >> + NULL, >> + NULL, >> + NULL, >> + &IoStatusBlock, >> + Entry, >> + Entry->EntrySize, >> + &ByteOffset, >> + NULL); >> + if (NT_SUCCESS(Status)) >> + { >> + if (IoStatusBlock.Information < Entry->EntrySize) >> + { >> + Status = STATUS_INSUFFICIENT_RESOURCES; >> + } >> + } >> + >> + return Status; >> } >> >> /* >> >> Modified: trunk/reactos/drivers/filters/mountmgr/device.c >> URL: >> http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filters/mountmgr/device.c?rev=69221&r1=69220&r2=69221&view=diff >> >> ============================================================================== >> --- trunk/reactos/drivers/filters/mountmgr/device.c [iso-8859-1] >> (original) >> +++ trunk/reactos/drivers/filters/mountmgr/device.c [iso-8859-1] Sun >> Sep 13 22:52:07 2015 >> @@ -1688,15 +1688,242 @@ >> return Status; >> } >> >> +/* >> + * @implemented >> + */ >> NTSTATUS >> MountMgrVolumeMountPointCreated(IN PDEVICE_EXTENSION DeviceExtension, >> IN PIRP Irp, >> IN NTSTATUS LockStatus) >> { >> - UNREFERENCED_PARAMETER(DeviceExtension); >> - UNREFERENCED_PARAMETER(Irp); >> - UNREFERENCED_PARAMETER(LockStatus); >> - return STATUS_NOT_IMPLEMENTED; >> + LONG Offset; >> + BOOLEAN Found; >> + NTSTATUS Status; >> + HANDLE RemoteDatabase; >> + PMOUNTDEV_UNIQUE_ID UniqueId; >> + PDATABASE_ENTRY DatabaseEntry; >> + PASSOCIATED_DEVICE_ENTRY AssociatedEntry; >> + PDEVICE_INFORMATION DeviceInformation, TargetDeviceInformation; >> + UNICODE_STRING LinkTarget, SourceDeviceName, SourceSymbolicName, >> TargetVolumeName, VolumeName, DbName; >> + >> + /* Initialize string */ >> + LinkTarget.Length = 0; >> + LinkTarget.MaximumLength = 0xC8; >> + LinkTarget.Buffer = AllocatePool(LinkTarget.MaximumLength); >> + if (LinkTarget.Buffer == NULL) >> + { >> + return STATUS_INSUFFICIENT_RESOURCES; >> + } >> + >> + /* If the mount point was created, then, it changed! >> + * Also use it to query some information >> + */ >> + Status = MountMgrVolumeMountPointChanged(DeviceExtension, Irp, >> LockStatus, &SourceDeviceName, &SourceSymbolicName, &TargetVolumeName); >> + /* Pending means DB are under synchronization, bail out */ >> + if (Status == STATUS_PENDING) >> + { >> + FreePool(LinkTarget.Buffer); >> + FreePool(SourceDeviceName.Buffer); >> + FreePool(SourceSymbolicName.Buffer); >> + return STATUS_PENDING; >> + } >> + else if (!NT_SUCCESS(Status)) >> + { >> + FreePool(LinkTarget.Buffer); >> + return Status; >> + } >> + >> + /* Query the device information */ >> + Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, >> &DeviceInformation); >> + if (!NT_SUCCESS(Status)) >> + { >> + /* If it failed, first try to get volume name */ >> + Status = QueryVolumeName(0, NULL, &SourceDeviceName, &LinkTarget, >> &VolumeName); >> + if (!NT_SUCCESS(Status)) >> + { >> + /* Then, try to read the symlink */ >> + Status = MountMgrQuerySymbolicLink(&SourceDeviceName, >> &LinkTarget); >> + if (!NT_SUCCESS(Status)) >> + { >> + FreePool(LinkTarget.Buffer); >> + FreePool(SourceDeviceName.Buffer); >> + FreePool(SourceSymbolicName.Buffer); >> + return Status; >> + } >> + } >> + else >> + { >> + FreePool(VolumeName.Buffer); >> + } >> + >> + FreePool(SourceDeviceName.Buffer); >> + >> + SourceDeviceName.Length = LinkTarget.Length; >> + SourceDeviceName.MaximumLength = LinkTarget.MaximumLength; >> + SourceDeviceName.Buffer = LinkTarget.Buffer; >> + >> + /* Now that we have the correct source, reattempt to query >> information */ >> + Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, >> FALSE, &DeviceInformation); >> + if (!NT_SUCCESS(Status)) >> + { >> + FreePool(SourceDeviceName.Buffer); >> + FreePool(SourceSymbolicName.Buffer); >> + return Status; >> + } >> + } >> + >> + FreePool(SourceDeviceName.Buffer); >> + >> + /* Get information about target device */ >> + Status = FindDeviceInfo(DeviceExtension, &TargetVolumeName, FALSE, >> &TargetDeviceInformation); >> + if (!NT_SUCCESS(Status)) >> + { >> + FreePool(SourceSymbolicName.Buffer); >> + return Status; >> + } >> + >> + /* Notify if not disabled */ >> + if (!TargetDeviceInformation->SkipNotifications) >> + { >> + PostOnlineNotification(DeviceExtension, >> &TargetDeviceInformation->SymbolicName); >> + } >> + >> + /* Open the remote database */ >> + RemoteDatabase = OpenRemoteDatabase(DeviceInformation, TRUE); >> + if (RemoteDatabase == 0) >> + { >> + FreePool(SourceSymbolicName.Buffer); >> + return STATUS_INSUFFICIENT_RESOURCES; >> + } >> + >> + /* Browse all the entries */ >> + Offset = 0; >> + Found = FALSE; >> + for (;;) >> + { >> + DatabaseEntry = GetRemoteDatabaseEntry(RemoteDatabase, Offset); >> + if (DatabaseEntry == NULL) >> + { >> + break; >> + } >> + >> + /* Try to find ourselves */ >> + DbName.MaximumLength = DatabaseEntry->SymbolicNameLength; >> + DbName.Length = DbName.MaximumLength; >> + DbName.Buffer = (PWSTR)((ULONG_PTR)DatabaseEntry + >> DatabaseEntry->SymbolicNameOffset); >> + if (RtlEqualUnicodeString(&TargetVolumeName, &DbName, TRUE)) >> + { >> + ++DatabaseEntry->DatabaseOffset; >> + Status = WriteRemoteDatabaseEntry(RemoteDatabase, Offset, >> DatabaseEntry); >> + FreePool(DatabaseEntry); >> + Found = TRUE; >> + break; >> + } >> + >> + Offset += DatabaseEntry->EntrySize; >> + FreePool(DatabaseEntry); >> + } >> + >> + /* We couldn't find ourselves, we'll have to add ourselves */ >> + if (!Found) >> + { >> + ULONG EntrySize; >> + PUNIQUE_ID_REPLICATE UniqueIdReplicate; >> + >> + /* Query the device unique ID */ >> + Status = QueryDeviceInformation(&TargetVolumeName, NULL, >> &UniqueId, NULL, NULL, NULL, NULL, NULL); >> + if (!NT_SUCCESS(Status)) >> + { >> + FreePool(SourceSymbolicName.Buffer); >> + CloseRemoteDatabase(RemoteDatabase); >> + return Status; >> + } >> + >> + /* Allocate a database entry */ >> + EntrySize = UniqueId->UniqueIdLength + TargetVolumeName.Length + >> sizeof(DATABASE_ENTRY); >> + DatabaseEntry = AllocatePool(EntrySize); >> + if (DatabaseEntry == NULL) >> + { >> + FreePool(UniqueId); >> + FreePool(SourceSymbolicName.Buffer); >> + CloseRemoteDatabase(RemoteDatabase); >> + return STATUS_INSUFFICIENT_RESOURCES; >> + } >> + >> + /* Fill it in */ >> + DatabaseEntry->EntrySize = EntrySize; >> + DatabaseEntry->DatabaseOffset = 1; >> + DatabaseEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY); >> + DatabaseEntry->SymbolicNameLength = TargetVolumeName.Length; >> + DatabaseEntry->UniqueIdOffset = TargetVolumeName.Length + >> sizeof(DATABASE_ENTRY); >> + DatabaseEntry->UniqueIdLength = UniqueId->UniqueIdLength; >> + RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + >> sizeof(DATABASE_ENTRY)), TargetVolumeName.Buffer, >> DatabaseEntry->SymbolicNameLength); >> + RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + >> DatabaseEntry->UniqueIdOffset), UniqueId->UniqueId, >> UniqueId->UniqueIdLength); >> + >> + /* And write it down */ >> + Status = AddRemoteDatabaseEntry(RemoteDatabase, DatabaseEntry); >> + FreePool(DatabaseEntry); >> + if (!NT_SUCCESS(Status)) >> + { >> + FreePool(UniqueId); >> + FreePool(SourceSymbolicName.Buffer); >> + CloseRemoteDatabase(RemoteDatabase); >> + return Status; >> + } >> + >> + /* And now, allocate an Unique ID item */ >> + UniqueIdReplicate = AllocatePool(sizeof(UNIQUE_ID_REPLICATE)); >> + if (UniqueIdReplicate == NULL) >> + { >> + FreePool(UniqueId); >> + FreePool(SourceSymbolicName.Buffer); >> + CloseRemoteDatabase(RemoteDatabase); >> + return Status; >> + } >> + >> + /* To associate it with the device */ >> + UniqueIdReplicate->UniqueId = UniqueId; >> + InsertTailList(&DeviceInformation->ReplicatedUniqueIdsListHead, >> &UniqueIdReplicate->ReplicatedUniqueIdsListEntry); >> + } >> + >> + /* We're done with the remote database */ >> + CloseRemoteDatabase(RemoteDatabase); >> + >> + /* Check we were find writing the entry */ >> + if (!NT_SUCCESS(Status)) >> + { >> + FreePool(SourceSymbolicName.Buffer); >> + return Status; >> + } >> + >> + /* This is the end, allocate an associated entry */ >> + AssociatedEntry = AllocatePool(sizeof(ASSOCIATED_DEVICE_ENTRY)); >> + if (AssociatedEntry == NULL) >> + { >> + FreePool(SourceSymbolicName.Buffer); >> + return STATUS_INSUFFICIENT_RESOURCES; >> + } >> + >> + /* Initialize its source name string */ >> + AssociatedEntry->String.Length = SourceSymbolicName.Length; >> + AssociatedEntry->String.MaximumLength = >> AssociatedEntry->String.Length + sizeof(UNICODE_NULL); >> + AssociatedEntry->String.Buffer = >> AllocatePool(AssociatedEntry->String.MaximumLength); >> + if (AssociatedEntry->String.Buffer == NULL) >> + { >> + FreePool(AssociatedEntry); >> + FreePool(SourceSymbolicName.Buffer); >> + return STATUS_INSUFFICIENT_RESOURCES; >> + } >> + >> + /* Copy data & insert in list */ >> + RtlCopyMemory(AssociatedEntry->String.Buffer, >> SourceSymbolicName.Buffer, SourceSymbolicName.Length); >> + AssociatedEntry->String.Buffer[SourceSymbolicName.Length / >> sizeof(WCHAR)] = UNICODE_NULL; >> + AssociatedEntry->DeviceInformation = DeviceInformation; >> + InsertTailList(&TargetDeviceInformation->AssociatedDevicesHead, >> &AssociatedEntry->AssociatedDevicesEntry); >> + >> + /* We're done! */ >> + FreePool(SourceSymbolicName.Buffer); >> + return STATUS_SUCCESS; >> } >> >> NTSTATUS >> >> Modified: trunk/reactos/drivers/filters/mountmgr/mntmgr.h >> URL: >> http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filters/mountmgr/mntmgr.h?rev=69221&r1=69220&r2=69221&view=diff >> >> ============================================================================== >> --- trunk/reactos/drivers/filters/mountmgr/mntmgr.h [iso-8859-1] >> (original) >> +++ trunk/reactos/drivers/filters/mountmgr/mntmgr.h [iso-8859-1] Sun >> Sep 13 22:52:07 2015 >> @@ -298,6 +298,36 @@ >> OUT PUNICODE_STRING VolumeName >> ); >> >> +HANDLE >> +OpenRemoteDatabase( >> + IN PDEVICE_INFORMATION DeviceInformation, >> + IN BOOLEAN MigrateDatabase >> +); >> + >> +PDATABASE_ENTRY >> +GetRemoteDatabaseEntry( >> + IN HANDLE Database, >> + IN LONG StartingOffset >> +); >> + >> +NTSTATUS >> +WriteRemoteDatabaseEntry( >> + IN HANDLE Database, >> + IN LONG Offset, >> + IN PDATABASE_ENTRY Entry >> +); >> + >> +NTSTATUS >> +CloseRemoteDatabase( >> + IN HANDLE Database >> +); >> + >> +NTSTATUS >> +AddRemoteDatabaseEntry( >> + IN HANDLE Database, >> + IN PDATABASE_ENTRY Entry >> +); >> + >> /* device.c */ >> >> DRIVER_DISPATCH MountMgrDeviceControl; >> @@ -458,4 +488,10 @@ >> IN BOOLEAN MarkOffline >> ); >> >> +NTSTATUS >> +MountMgrQuerySymbolicLink( >> + IN PUNICODE_STRING SymbolicName, >> + IN OUT PUNICODE_STRING LinkTarget >> +); >> + >> #endif /* _MNTMGR_H_ */ >> >> Modified: trunk/reactos/drivers/filters/mountmgr/mountmgr.c >> URL: >> http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filters/mountmgr/mountmgr.c?rev=69221&r1=69220&r2=69221&view=diff >> >> ============================================================================== >> --- trunk/reactos/drivers/filters/mountmgr/mountmgr.c [iso-8859-1] >> (original) >> +++ trunk/reactos/drivers/filters/mountmgr/mountmgr.c [iso-8859-1] Sun >> Sep 13 22:52:07 2015 >> @@ -48,7 +48,6 @@ >> * - MountMgrQueryDosVolumePaths >> * - MountMgrQueryVolumePaths >> * - MountMgrValidateBackPointer >> - * - MountMgrVolumeMountPointCreated >> * - MountMgrVolumeMountPointDeleted >> * - ReconcileThisDatabaseWithMasterWorker >> */ >> >> >> > > > > _______________________________________________ > Ros-dev mailing list > Ros-dev@reactos.org > http://www.reactos.org/mailman/listinfo/ros-dev >
-- Pierre Schweitzer <pierre at reactos.org> System & Network Administrator Senior Kernel Developer ReactOS Deutschland e.V.
smime.p7s
Description: S/MIME Cryptographic Signature
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev