yes Best regards, Alex Ionescu
On Mon, Sep 14, 2015 at 3:16 AM, Pierre Schweitzer <pie...@reactos.org> wrote: > 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. > > > _______________________________________________ > Ros-dev mailing list > Ros-dev@reactos.org > http://www.reactos.org/mailman/listinfo/ros-dev > >
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev