[ros-dev] [ros-diffs] [pschweitzer] 69221: [MOUNTMGR] Implement the IOCTL IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED: - Implement WriteRemoteDatabaseEntry() - Implement MountMgrVolumeMountPointCreated()
Alex Ionescu
ionucu at videotron.ca
Wed Sep 16 00:25:58 UTC 2015
yes
Best regards,
Alex Ionescu
On Mon, Sep 14, 2015 at 3:16 AM, Pierre Schweitzer <pierre at 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, <pschweitzer at 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 at 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 at reactos.org
> http://www.reactos.org/mailman/listinfo/ros-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.reactos.org/pipermail/ros-dev/attachments/20150915/3cc5f2a4/attachment-0001.html>
More information about the Ros-dev
mailing list