[PATCH] kernelbase: Fix stack overflow by DefineDosDeviceW().
Xu Wei
xuwei at uniontech.com
Wed Mar 9 00:34:37 CST 2022
Signed-off-by: Xu Wei <xuwei at uniontech.com>
---
dlls/kernel32/tests/volume.c | 10 ++++++++++
dlls/kernelbase/volume.c | 17 +++++++++++++++--
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c
index 3bc3c7e4872..10746dd6507 100644
--- a/dlls/kernel32/tests/volume.c
+++ b/dlls/kernel32/tests/volume.c
@@ -112,6 +112,7 @@ static void test_dos_devices(void)
{
char buf[MAX_PATH], buf2[400];
char drivestr[3];
+ WCHAR drivestrW[3];
HANDLE file;
BOOL ret;
@@ -186,6 +187,15 @@ static void test_dos_devices(void)
ret = QueryDosDeviceA( drivestr, buf, sizeof(buf) );
ok(!ret, "expected failure\n");
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "got error %lu\n", GetLastError());
+
+ SetLastError(0);
+ ret = DefineDosDeviceW( DDD_RAW_TARGET_PATH, drivestrW, NULL );
+ ok(!ret, "expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError());
+
+ SetLastError(0);
+ ret = DefineDosDeviceW ( DDD_RAW_TARGET_PATH,L"C:/windows/",L"\\Device\\C:/windows/" );
+ ok(ret, "got error %u\n", GetLastError());
}
static void test_FindFirstVolume(void)
diff --git a/dlls/kernelbase/volume.c b/dlls/kernelbase/volume.c
index 39386867aa3..d604ee02500 100644
--- a/dlls/kernelbase/volume.c
+++ b/dlls/kernelbase/volume.c
@@ -384,7 +384,7 @@ err_ret:
*/
BOOL WINAPI DECLSPEC_HOTPATCH DefineDosDeviceW( DWORD flags, const WCHAR *device, const WCHAR *target )
{
- WCHAR link_name[15] = L"\\DosDevices\\";
+ WCHAR *link_name = NULL;
UNICODE_STRING nt_name, nt_target;
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
@@ -395,17 +395,28 @@ BOOL WINAPI DECLSPEC_HOTPATCH DefineDosDeviceW( DWORD flags, const WCHAR *device
if (flags & ~(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION))
FIXME("Ignoring flags %#lx.\n", flags & ~(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION));
- lstrcatW( link_name, device );
+ if (!(link_name = HeapAlloc( GetProcessHeap(), 0, sizeof(L"\\DosDevices\\") + (device ? lstrlenW(device)*sizeof(WCHAR) : 0))))
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ lstrcpyW( link_name, L"\\DosDevices\\" );
+ if (device) lstrcatW( link_name, device );
RtlInitUnicodeString( &nt_name, link_name );
InitializeObjectAttributes( &attr, &nt_name, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 0, NULL );
if (flags & DDD_REMOVE_DEFINITION)
{
if (!set_ntstatus( NtOpenSymbolicLinkObject( &handle, 0, &attr ) ))
+ {
+ HeapFree( GetProcessHeap(), 0, link_name );
return FALSE;
+ }
status = NtMakeTemporaryObject( handle );
NtClose( handle );
+ HeapFree( GetProcessHeap(), 0, link_name );
return set_ntstatus( status );
}
@@ -414,6 +425,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH DefineDosDeviceW( DWORD flags, const WCHAR *device
if (!RtlDosPathNameToNtPathName_U( target, &nt_target, NULL, NULL))
{
SetLastError( ERROR_PATH_NOT_FOUND );
+ HeapFree( GetProcessHeap(), 0, link_name );
return FALSE;
}
}
@@ -422,6 +434,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH DefineDosDeviceW( DWORD flags, const WCHAR *device
if (!(status = NtCreateSymbolicLinkObject( &handle, SYMBOLIC_LINK_ALL_ACCESS, &attr, &nt_target )))
NtClose( handle );
+ HeapFree( GetProcessHeap(), 0, link_name );
return set_ntstatus( status );
}
--
2.20.1
More information about the wine-devel
mailing list