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.

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

_______________________________________________
Ros-dev mailing list
Ros-dev@reactos.org
http://www.reactos.org/mailman/listinfo/ros-dev

Reply via email to