yes
Best regards,
Alex Ionescu
On Mon, Sep 14, 2015 at 3:16 AM, Pierre Schweitzer <pierre(a)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(a)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/d…
>
>
==============================================================================
> ---
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/d…
>
>
==============================================================================
> ---
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/m…
>
>
==============================================================================
> ---
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/m…
>
>
==============================================================================
>> --- 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(a)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(a)reactos.org
http://www.reactos.org/mailman/listinfo/ros-dev