Alexandre Julliard : mountmgr: Fix handling of buffer overflows in IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE.
Alexandre Julliard
julliard at winehq.org
Thu Jul 9 17:10:39 CDT 2020
Module: wine
Branch: master
Commit: bc8d04d6a502b47ecc219bb2fc1000c391e20189
URL: https://source.winehq.org/git/wine.git/?a=commit;h=bc8d04d6a502b47ecc219bb2fc1000c391e20189
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Jul 9 10:09:49 2020 +0200
mountmgr: Fix handling of buffer overflows in IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mountmgr.sys/mountmgr.c | 42 +++++++++++-------------------------------
1 file changed, 11 insertions(+), 31 deletions(-)
diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c
index 6393dbf022..1961eab983 100644
--- a/dlls/mountmgr.sys/mountmgr.c
+++ b/dlls/mountmgr.sys/mountmgr.c
@@ -328,6 +328,7 @@ static NTSTATUS query_unix_drive( void *buff, SIZE_T insize,
}
size = sizeof(*output);
+ if (label) size += (strlenW(label) + 1) * sizeof(WCHAR);
if (device) size += strlen(device) + 1;
if (mount_point) size += strlen(mount_point) + 1;
@@ -342,54 +343,33 @@ static NTSTATUS query_unix_drive( void *buff, SIZE_T insize,
output->device_offset = 0;
output->label_offset = 0;
- if (size > outsize)
- {
- iosb->Information = 0;
- if (size >= FIELD_OFFSET( struct mountmgr_unix_drive, size ) + sizeof(output->size))
- {
- output->size = size;
- iosb->Information = FIELD_OFFSET( struct mountmgr_unix_drive, size ) + sizeof(output->size);
- }
- if (size >= FIELD_OFFSET( struct mountmgr_unix_drive, type ) + sizeof(output->type))
- {
- output->type = type;
- iosb->Information = FIELD_OFFSET( struct mountmgr_unix_drive, type ) + sizeof(output->type);
- }
- status = STATUS_BUFFER_OVERFLOW;
- goto done;
- }
-
ptr = (char *)(output + 1);
- if (mount_point)
+ if (label && ptr + (strlenW(label) + 1) * sizeof(WCHAR) - (char *)output <= outsize)
+ {
+ output->label_offset = ptr - (char *)output;
+ strcpyW( (WCHAR *)ptr, label );
+ ptr += (strlenW(label) + 1) * sizeof(WCHAR);
+ }
+ if (mount_point && ptr + strlen(mount_point) + 1 - (char *)output <= outsize)
{
output->mount_point_offset = ptr - (char *)output;
strcpy( ptr, mount_point );
ptr += strlen(ptr) + 1;
}
- else output->mount_point_offset = 0;
-
- if (device)
+ if (device && ptr + strlen(device) + 1 - (char *)output <= outsize)
{
output->device_offset = ptr - (char *)output;
strcpy( ptr, device );
ptr += strlen(ptr) + 1;
}
- else output->device_offset = 0;
-
- if (label)
- {
- output->label_offset = ptr - (char *)output;
- strcpyW( (WCHAR *)ptr, label );
- ptr += (strlenW(label) + 1) * sizeof(WCHAR);
- }
- else output->label_offset = 0;
TRACE( "returning %c: dev %s mount %s type %u\n",
letter, debugstr_a(device), debugstr_a(mount_point), type );
iosb->Information = ptr - (char *)output;
-done:
+ if (size > outsize) status = STATUS_BUFFER_OVERFLOW;
+
RtlFreeHeap( GetProcessHeap(), 0, device );
RtlFreeHeap( GetProcessHeap(), 0, mount_point );
RtlFreeHeap( GetProcessHeap(), 0, label );
More information about the wine-cvs
mailing list